加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

sql-server – 为什么添加TOP 1会显着恶化性能?

发布时间:2020-12-31 04:13:09 所属栏目:编程 来源:网络整理
导读:我有一个相当简单的查询 SELECT TOP 1 dc.DOCUMENT_ID,dc.COPIES,dc.REQUESTOR,dc.D_ID,cj.FILE_NUMBERFROM DOCUMENT_QUEUE dcJOIN CORRESPONDENCE_JOURNAL cj ON dc.DOCUMENT_ID = cj.DOCUMENT_IDWHERE dc.QUEUE_DATE = GETDATE() AND dc.PRINT_LOCATION = 2

我有一个相当简单的查询

SELECT TOP 1 dc.DOCUMENT_ID,dc.COPIES,dc.REQUESTOR,dc.D_ID,cj.FILE_NUMBER
FROM DOCUMENT_QUEUE dc
JOIN CORRESPONDENCE_JOURNAL cj
    ON dc.DOCUMENT_ID = cj.DOCUMENT_ID
WHERE dc.QUEUE_DATE <= GETDATE()
  AND dc.PRINT_LOCATION = 2
ORDER BY cj.FILE_NUMBER

这给了我可怕的表现(从来没有费心等待它完成).查询计划如下所示:

但是,如果我删除TOP 1,我会得到一个看起来像这样的计划,并在1-2秒内运行:

正确的PK&索引如下.

TOP 1改变了查询计划的事实并没有让我感到惊讶,我只是有点惊讶它让它变得更糟.

注意:我已经阅读了post的结果并理解了行目标等的概念.我很好奇的是如何更改查询以便它使用更好的计划.目前我正在将数据转储到临时表中,然后从中拉出第一行.我想知道是否有更好的方法.

编辑对于在此之后阅读此内容的人,这里有一些额外的信息.

> Document_Queue – PK / CI是D_ID,它有~5k行.
> Correspondence_Journal – PK / CI是FILE_NUMBER,CORRESPONDENCE_ID,它有~1.4 mil的行.

当我开始时没有其他索引.我在Correspondence_Journal(Document_Id,File_Number)上找到了一个

解决方法

尝试强制加入 hash *
SELECT TOP 1 
       dc.DOCUMENT_ID,cj.FILE_NUMBER
FROM DOCUMENT_QUEUE dc
INNER HASH JOIN CORRESPONDENCE_JOURNAL cj
        ON dc.DOCUMENT_ID = cj.DOCUMENT_ID
       AND dc.QUEUE_DATE <= GETDATE()
       AND dc.PRINT_LOCATION = 2
ORDER BY cj.FILE_NUMBER

优化器可能认为前一个循环会更好,而这种情况有意义,但实际上它在这里不起作用.这里只是一个猜测,但也许该假脱机的估计成本已关闭 – 它使用TEMPDB – 您的TEMPDB可能表现不佳.

*注意join hints,因为它们强制计划表访问顺序与查询中表的写入顺序相匹配(就像指定了OPTION(FORCE ORDER)).从文档链接:

这可能不会在示例中产生任何不良影响,但总的来说,它可能会很好. FORCE ORDER(隐含或显式)是一个非常强大的提示,超出了强制执行的顺序;它阻止了广泛的优化器技术的应用,包括部分聚合和重新排序.

在适当的情况下,OPTION(HASH JOIN)查询提示可能不那么具有侵入性,因为这并不意味着FORCE ORDER.但是,它确实适用于查询中的所有联接.其他解决方案可用.

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读