如何优化嵌套查询

时间:2010-11-25 11:33:29

标签: sql sql-server-2005 query-optimization

我有很多查询,如:

     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,00,000记录的表。因此需要花费大量时间,有时会抽出时间。

由于

3 个答案:

答案 0 :(得分:1)

您应该将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

虽然finalquery是以下

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

答案 1 :(得分:0)

你可以尝试去标准化一点:

  1. 创建repliesNewPostNotClear字段
  2. 编写一个更新这些字段的例程,cron它(句点取决于3。)
  3. 重写影响这些字段的大多数/所有查询以更新它们。如果你重写所有,每天运行2.几次。否则,根据您需要的数据完整性,每小时几次。
  4. 这显然有助于您的查询。但是,它需要更多的维护,因为任何几乎从未使用过的小查询都会破坏一致性(想想一些像BB一样的调节工具,比如拆分主题......)

答案 2 :(得分:0)

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

我无法对此进行测试,因此可能存在一些语法错误,但是你得到了漂移?