原来的查询:
SELECT V.Date, V.Amount, I.Number
FROM Values V
JOIN Items I ON V.ItemId = I.Id AND I.AssetId = V.AssetId
WHERE I.Type IN (10023, 10025) AND V.AssetId = 100
ORDER BY V.Date
超时后一定很长一段时间。关于戳了一下后,我注释掉ORDER BY
:
SELECT V.Date, V.Amount, I.Number
FROM Values V
JOIN Items I ON V.ItemId = I.Id AND I.AssetId = V.AssetId
WHERE I.Type IN (10023, 10025) AND V.AssetId = 100
--ORDER BY V.Date
这在零个米利斯返回两行。
我的印象是,查询完成后会出现为了通过针对JOIN,也就是说,它将使一个临时(名字吗?)对结果表,然后命令他们。显然,这种印象是错误的。
有什么建议么?我没有SHOWPLAN(等全部)在此服务器上,所以我在黑暗中的一点。
ORDER BY
会影响执行计划。如果查询确实只返回两行,然后超时是令人惊讶的。
我想重写查询为:
SELECT V.Date, V.Amount, I.Number
FROM Values V JOIN
Items I
ON V.ItemId = I.Id AND I.AssetId = V.AssetId
WHERE I.Type IN (10023, 10025) AND I.AssetId = 100
-----------------------------------^ the only change
ORDER BY V.Date;
那么最好的指标是Items(AssetId, Type, Id, Number)
和Values(ItemId, Assetid, Date, Amount)
。这些覆盖索引的查询。
这很难不执行计划来解决。
我会做的第一件事是确保统计数据是最新的。如果统计数据不是最新的,SQL会产生低效率的计划。
如果你不能做到这一点,你可以改变你的查询强制正确的计划。
例如,你可以使用一个表变量,以确保ORDER BY是最后完成。
--declare staging table
declare @stage([Date] date, [Amount] decimal(19,4), [Number] int);
--insert data into staging table
INSERT INTO @stage([Date], [Amount], [Number])
SELECT V.Date, V.Amount, I.Number
FROM Values V
JOIN Items I ON V.ItemId=I.Id AND I.AssetId=V.AssetId
WHERE I.Type IN (10023, 10025) AND V.AssetId=100) as t1;
--retrieve data from staging table with sorting
SELECT * FROM @stage ORDER BY Date;
这不是理想的,但如果你没有DBA权限,这是你能做的最好的。
尝试另一件事是使用MAXDOP 1提示。这告诉SQL引擎不使用并行执行,有时会有助于避免低效率的计划。
SELECT V.Date, V.Amount, I.Number
FROM Values V
JOIN Items I ON V.ItemId=I.Id AND I.AssetId=V.AssetId
WHERE I.Type IN (10023, 10025) AND V.AssetId=100) as t1
ORDER BY Date
OPTION (MAXDOP 1);
请注意,我刚才添加OPTION(MAXDOP 1)原始查询。