使用TOP和ORDER BY的查询非常慢

时间:2019-04-11 11:55:56

标签: sql sql-server tsql inner-join top-n

我在SQL Server 2014中有一个查询,执行该查询会花费很多时间。

当我删除TOPORDER 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

我如何使其更快?

4 个答案:

答案 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)上具有索引。该执行计划将从头开始扫描索引,然后对DateValueId进行测试,并为相应的匹配行返回ColumnValue

但是,我不认为SQL Server会生成此计划(尽管值得尝试),而且我不知道如何不执行该计划。