2013-10-02 21 views
0

我已經給出了一個任務來優化下面的SQL查詢。目前它表現糟糕。我爲它運行了執行計劃,並且我看到它正在執行羣集索引掃描,並且其成本非常高。我怎樣才能降低成本或可以改變它使用索引搜索呢?羣集索引成本高使用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 

enter image description here

enter image description here

+1

沒有付出任何真正的努力來查看您的查詢......每當我看到一個緩慢的查詢使用'OR',我嘗試使用'UNION'。您需要確定您嘗試使用哪些索引,並找出它們未被使用的原因(或者在必要時創建它們) –

+0

緩慢索引的碎片級別是什麼? – Volvox

回答

0

有一點需要注意:CustomerTypeID <> 1將不能有效使用索引作爲CustomerTypeID> 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(看起來像你上面這個混亂) 。