原始查询:
add_filter('wpi_notification_message', 'remove_slashes');
function remove_slashes($message){
return stripslashes($message);
}
一段时间后超时。戳了一下之后,我注释了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
这将以零毫秒返回两行。
给我的印象是,在查询完成之后,将对JOIN进行排序,也就是说,它将为结果创建一个临时表(名称?),然后对其进行排序。显然,这种印象是错误的。
有什么建议吗?我在此服务器上没有SHOWPLAN(全部),所以我有点茫然。
答案 0 :(得分:1)
(make-array rows)
可能会影响执行计划。如果查询确实只返回两行,那么超时是令人惊讶的。
我将查询重写为:
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)
。这些覆盖了查询的索引。
答案 1 :(得分:0)
没有执行计划就很难进行故障排除。
我要做的第一件事是确保统计信息是最新的。如果统计信息不是最新的,则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)。