使用Sql Query,群集索引成本很高

时间:2013-10-02 18:45:18

标签: tsql sql-server-2008-r2 query-performance

我已经给出了优化以下sql查询的任务。它目前表现糟糕。我为它运行了执行计划,我发现它正在进行Clustered Index Scan,而且它的成本非常高。如何降低成本,或者可以将其更改为使用索引搜索?

SELECT TOP 20 CustomerPrimaryExtID,
              Max(POSTimeStamp)     AS TransactionDate,
              ExtLocationCode,
              0                     AS RedemptionAmount,
              0                     AS RedemptionCount,
              TerminalNum,
              LogixTransNum,
              POSTransNum           AS TransNum,
              0                     AS DetailRecords,
              CustomerTypeID,
              PresentedCustomerID,
              PresentedCardTypeID,
              HHID,
              Replayed,
              0                     AS TransContext,
              isnull(TransTotal, 0) AS TransTotal

FROM   TransHist AS TH WITH(nolock)
WHERE  ( ( ( CustomerPrimaryExtID IN ( '' )
             AND HHID IS NULL )            

            OR HHID = '0000000250000013408'
               AND CustomerTypeID <> 1 )                            

          OR ( CustomerPrimaryExtID = '0000000250000013408'
               AND CustomerTypeID = 1 ) )           

       AND NOT EXISTS (SELECT LogixTransNum
                       FROM   TransRedemption AS TR2 with(nolock)
                       WHERE  ( ( ( CustomerPrimaryExtID IN ( '' )
                                    AND HHID IS NULL )
                                   OR HHID = '0000000250000013408'
                                      AND CustomerTypeID <> 1 )
                                 OR ( CustomerPrimaryExtID = '0000000250000013408'
                                      AND CustomerTypeID = 1 ) )
                              AND TH.LogixTransNum = TR2.LogixTransNum)

GROUP  BY CustomerPrimaryExtID,
          HHID,
          CustomerTypeID,
          PresentedCustomerID,
          PresentedCardTypeID,
          LogixTransNum,
          POSTransNum,
          TerminalNum,
          ExtLocationCode,
          Replayed,
          TransTotal
ORDER  BY TransactionDate DESC 

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:0)

需要注意的一点是:CustomerTypeID <> 1不会像CustomerTypeID那样有效地使用索引&gt; 1,见下面的测试例子。此外,WHERE NOT EXISTSNOT IN也是性能杀手。

CREATE TABLE NumberCrazy(
    IntegersAreCool INT
)

-- Run this 20+ times
INSERT INTO NumberCrazy
VALUES (1)

-- Run this twice
DECLARE @begin INT = 1, @max INT = 2000, @r INT

WHILE @begin <= @max
BEGIN

    SET @r = (RAND()*(@begin))

    INSERT INTO NumberCrazy
    SELECT @r

    SET @begin = @begin + 1

END

CREATE CLUSTERED INDEX [IX_DaInts] ON [dbo].[NumberCrazy]
(
    [IntegersAreCool] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

GO

SET STATISTICS IO ON

SELECT *
FROM NumberCrazy
WHERE IntegersAreCool > 1

SELECT *
FROM NumberCrazy
WHERE IntegersAreCool <> 1

结果:

表'NumberCrazy'。扫描计数1,逻辑读取12,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。

表'NumberCrazy'。扫描计数2,逻辑读取15,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。

NOTE THE EXECUTION PLAN(看起来就像你上面的混乱)。