我在SQL Server 2014中有一个查询,执行该查询会花费很多时间。
当我删除TOP
或ORDER BY
指令时,它的执行速度更快,但是如果我同时编写它们,则将花费很多时间。
SELECT TOP (10) A.ColumnValue AS ValueA
FROM TableA AS A
INNER JOIN TableB AS B
ON A.ID = B.ID
WHERE A.DateValue > '1982-05-02'
ORDER BY ValueA
我如何使其更快?
答案 0 :(得分:2)
您说
当我删除TOP 或 ORDER BY ...时,它执行得更快
这将表明SQL Server可以按期望的顺序生成整个结果集没有问题。梨形限制TOP 10
。这是rowgoals的常见问题。当SQL Server知道您只需要前几个结果时,它可以选择其他计划来尝试针对这种情况进行适得其反的优化。
较新的版本包括提示DISABLE_OPTIMIZER_ROWGOAL
,以根据每个查询禁用此提示。在较旧的版本上,您可以按以下方式使用QUERYTRACEON 4138
。
SELECT TOP (10) A.ColumnValue AS ValueA
FROM TableA AS A
INNER JOIN TableB AS B
ON A.ID = B.ID
WHERE A.DateValue > '1982-05-02'
ORDER BY ValueA
OPTION (QUERYTRACEON 4138)
您可以使用它来确认原因,但可能会发现运行QUERYTRACEON
的权限是一个问题。
在这种情况下,您可以将TOP
值隐藏在如下变量中
DECLARE @Top INT = 10
SELECT TOP (@Top) A.ColumnValue AS ValueA
FROM TableA AS A
INNER JOIN TableB AS B
ON A.ID = B.ID
WHERE A.DateValue > '1982-05-02'
ORDER BY ValueA
option (optimize for (@Top = 1000000))
答案 1 :(得分:1)
基于两个表的ID
列创建索引
CREATE INDEX index_nameA
ON TableA (ID, DateValue)
;
CREATE INDEX index_nameB
ON TableB (ID)
它将在查询执行时创建更好的计划
答案 2 :(得分:0)
最好的方法是使用索引来提高性能。 在这种情况下,可以在此放置索引(date_value)。 有关索引的使用,请参考以下URL:using indexes
答案 3 :(得分:0)
这几乎是没有希望的,除非您的大多数数据都具有较早的日期。如果日期特殊,则可以创建一个计算的持久列以总体上加快查询速度。但是,我怀疑情况就是如此。
我可以为这样的查询设想一个更好的执行计划:
SELECT TOP (10) A.ColumnValue AS ValueA
FROM TableA A
WHERE EXISTS (SELECT 1 FROM TableB b WHERE A.ID = B.ID) AND
A.DateValue > '1982-05-02'
ORDER BY ValueA;
,在TableA(ValueA, DateValue, Id, ColumnValue)
和TableB(id)
上具有索引。该执行计划将从头开始扫描索引,然后对DateValue
和Id
进行测试,并为相应的匹配行返回ColumnValue
。
但是,我不认为SQL Server会生成此计划(尽管值得尝试),而且我不知道如何不执行该计划。