Как оптимизировать вложенный запрос - PullRequest
0 голосов
/ 25 ноября 2010

у меня есть много запросов, которые написаны как:

     select  thread_id as topic_id,title as topic            
  ,            
    isnull((select count(*) from tblmessages b where thread_id=a.thread_id and is_approved='Y' and sort_level>1            
     group by b.thread_id            
     ),0) as replies,            
    isnull((select count(*) from tblmessages b where thread_id=a.thread_id and isnull(new_post,'Y')='Y' and sort_level>1            
     group by b.thread_id            
     ),0) as NewPost,            
    isnull((select count(*) from tblmessages b where thread_id=a.thread_id and isnull(is_approved,'N')='N' and sort_level>1            
     group by b.thread_id            
     ),0) as NotClear,            

    sort_level,sort_index,  from tblMessages a            
    where   sort_level=1 and category=@category 
    order by topic_id desc

Подскажите, пожалуйста, как оптимизировать и как лучше написать такие запросы. потому что у меня есть таблицы с записями 5 000 000. так что это занимает много времени, а иногда выходит время.

Спасибо

Ответы [ 3 ]

1 голос
/ 25 ноября 2010

Вы должны сгруппировать подзапрос variuos в один с разным количеством и использовать объединение для объединения данных

подзапрос должен быть:

select thread_id
     count(when isnull(is_approved,'N')='N' then 1 end) as replies,
     count(when isnull(new_post,'Y')='Y' then 1 end) as NewPost,
     count(when isnull(is_approved,'N')='N' then 1 end) as NotClear
     from tblmessages 
     where sort_level>1  
     group by thread_id

В то время как последнийследующий

select  thread_id as topic_id,title as topic,
   sort_level,sort_index , B.replies, B.NewPost, B.NotClear
   from tblMessages a            
   join
     (select thread_id
     count(when isnull(is_approved,'N')='N' then 1 end) as replies,
     count(when isnull(new_post,'Y')='Y' then 1 end) as NewPost,
     count(when isnull(is_approved,'N')='N' then 1 end) as NotClear
     from tblmessages 
     where sort_level>1  
     group by thread_id) as B
     on a.thread_id = B.thread_id
    where   sort_level=1 and category=@category 
    order by topic_id desc
0 голосов
/ 25 ноября 2010
SELECT a.* 
FROM 
    (SELECT   
        thread_id AS topic_id,
        title AS topic ,
        SUM(CASE WHEN is_approved='Y' AND sort_level > 1 THEN 1 ELSE 0 END) as replies, 
        SUM(CASE WHEN isnull(new_post,'Y')='Y' AND sort_level > 1 THEN 1 ELSE 0) END as NewPost, 
        SUM(CASE WHEN isnull(is_approved,'N')='N' AND sort_level > 1 THEN 1 ELSE 0 END) as NotClear, 
        sort_level ,
        sort_index,  
        category ,
        topic_id
    FROM 
        tblMessages 
    ) a
WHERE 
    a.sort_level=1 AND a.category=@category 
ORDER BY 
        a.topic_id DESC

Я не смог проверить это, поэтому могут существовать некоторые синтаксические ошибки, но вы получаете дрейф?

0 голосов
/ 25 ноября 2010

Вы можете немного отменить нормализацию:

  1. Создать replies, NewPost и NotClear поля
  2. Написать подпрограмму, которая обновляет эти поля, cron it (период зависит от 3.)
  3. Переписать большинство / все запросы, которые влияют на эти поля, чтобы обновить их.Если вы переписываете все, запускайте 2. несколько раз в день.В противном случае, в зависимости от требуемой целостности данных, несколько раз в час.

Это, несомненно, поможет с вашим запросом.Тем не менее, он нуждается в дополнительном обслуживании, так как любой небольшой запрос, почти никогда не используемый, может нарушить согласованность (подумайте о некоторых модерирующих инструментах для BB, таких как разделенная тема ...)

...