SQL Server:计数请求优化

时间:2015-05-31 03:56:40

标签: sql sql-server-2008 query-optimization bigdata

我正在寻找一种解决方案来优化我在一些大桌子上运行的选择查询(每桌超过100M项目),这是我目前正在使用的解决方案,它需要超过40分钟!!

SELECT Count(a.id) 
FROM   tablea a 
       JOIN tableb b 
         ON a.ref_xid = b.xid 
            AND a.ref_yid = b.yid 
WHERE  ( b.filtre = 1 
          OR b.filtre = 7 ) 
       AND NOT EXISTS (SELECT id 
                       FROM   tablec 
                       WHERE  xid = a.xid 
                              AND yid = a.yid); 

4 个答案:

答案 0 :(得分:1)

对于此查询:

SELECT Count(a.id) 
FROM tablea a JOIN
     tableb b 
     ON a.ref_xid = b.xid AND a.ref_yid = b.yid 
WHERE b.filtre IN (1, 7) AND 
      NOT EXISTS (SELECT 1 
                  FROM   tablec c
                  WHERE  c.xid = a.xid AND c.yid = a.yid
                 ); 

您想要tableb(filtre, xid, yid)tablea(ref_xid, ref_yid)tablec(xid, yid)上的索引。

答案 1 :(得分:0)

这不是问题的问题,而是机器必须经历的I / O量。

@Html.ActionImageLink("Controller", "action/url", null, null, Url.Content("image/location"), null)

要限制这一点,你应该

  • 向表中添加(相关)索引,以确保只需要运行所需的记录
  • 添加'覆盖'索引,以确保当找到索引中的相关入口点时,他们服务器不需要返回到表中的记录,以便找出所需的其他字段但是未包含在索引中

至于你给出的例子,我说你需要以下索引才能获得最佳性能:

SELECT Count(*) 
  FROM tablea a 
  JOIN tableb b 
    ON b.xid = a.ref_xid 
   AND b.yid = a.ref_yid
   AND b.filtre IN (1, 7) 
   AND NOT EXISTS (SELECT * 
                     FROM tablec c
                    WHERE c.xid = a.xid 
                      AND c.yid = a.yid); 

(我假设所有表格都已在CREATE INDEX idx_filtre ON tableb (filtre) INCLUDE (xid, yid) CREATE INDEX idx_ids ON tablec (xid, yid) CREATE INDEX idx_refids ON tablea (ref_xid, ref_yid) INCLUDE (xid, yid) 字段上拥有群集PK)

PS:查询执行计划是你的朋友。

答案 2 :(得分:0)

最终的解决方案是使用临时表并将请求分为两个步骤。 第一个只在临时表中进行数据准备,第二个用于处理临时表并应用更改。

答案 3 :(得分:-1)

你可以使用temp tebles:

;
WITH    q1
          AS ( SELECT   *
               FROM     tableB b
               WHERE    b.filtre = 1
                        OR b.filtre = 7
             ),
        q2
          AS ( SELECT   *
               FROM     tableA a
               WHERE    NOT EXISTS ( SELECT id
                                     FROM   tableC
                                     WHERE  xid = a.xid
                                            AND yid = a.yid )
             )
    SELECT  COUNT(a.id)
    FROM    tableA a
            JOIN tableB b ON a.ref_xid = b.xid
                             AND a.ref_yid = b.yid