0

我已经给了一个任务来优化下面的 sql 查询。它目前表现不佳。我为它运行了执行计划,我看到它在做聚集索引扫描,它的成本非常高。我怎样才能降低成本,或者可以将其更改为使用索引搜索?

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 

在此处输入图像描述

在此处输入图像描述

4

1 回答 1

0

需要注意的一件事:CustomerTypeID <> 1不会像 CustomerTypeID > 1 那样有效地使用索引,请参见下面的测试示例。此外,WHERE NOT EXISTS或者NOT 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(看起来你上面的混乱)。

于 2013-10-02T22:05:28.787 回答