我已经给出了优化以下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
答案 0 :(得分:0)
需要注意的一点是:CustomerTypeID <> 1
不会像CustomerTypeID那样有效地使用索引&gt; 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
(看起来就像你上面的混乱)。