【发布时间】:2014-05-06 14:20:04
【问题描述】:
我遇到了 SQL Server 2008 R2 的问题。如果我执行下面的语句,只需要不到 1 秒。
SELECT
A.REFERENCE_DATE AS REFERENCE_DATE
,A.MIS_BANK_ID AS BANK_ID
,'Unknown credit line' AS QUERY_LOG
,'STG_MIS_CREDIT_LINES_VALUE' AS [TABLE]
,'MIS_CREDIT_LINE_BRANCH_ID - MIS_CREDIT_LINE_ID' AS FIELD
,( 'MIS_CREDIT_LINE_BRANCH_ID: ' + A.MIS_CREDIT_LINE_BRANCH_ID + ' # MIS_CREDIT_LINE_ID: ' + A.MIS_CREDIT_LINE_ID ) AS [KEY]
,( A.MIS_CREDIT_LINE_BRANCH_ID + ' - ' + A.MIS_CREDIT_LINE_ID ) AS RESULT_1
,NULL AS RESULT_2
,NULL AS OUTSTANDING
FROM
STG_MIS_CREDIT_LINES_VALUE A
LEFT JOIN
STG_MIS_REG_CREDIT_LINES B ON A.REFERENCE_DATE = B.REFERENCE_DATE
AND A.MIS_BANK_ID = B.MIS_BANK_ID
AND A.MIS_CREDIT_LINE_BRANCH_ID = B.MIS_CREDIT_LINE_BRANCH_ID
AND A.MIS_CREDIT_LINE_ID = B.MIS_CREDIT_LINE_ID
WHERE
B.MIS_CREDIT_LINE_ID IS NULL
AND A.REFERENCE_DATE = '20131231'
当我在顶部添加“SET ROWCOUNT 1”语句时,执行需要超过 20 分钟!
SET ROWCOUNT 1
SELECT
A.REFERENCE_DATE AS REFERENCE_DATE
,A.MIS_BANK_ID AS BANK_ID
,'Unknown credit line' AS QUERY_LOG
,'STG_MIS_CREDIT_LINES_VALUE' AS [TABLE]
,'MIS_CREDIT_LINE_BRANCH_ID - MIS_CREDIT_LINE_ID' AS FIELD
,( 'MIS_CREDIT_LINE_BRANCH_ID: ' + A.MIS_CREDIT_LINE_BRANCH_ID + ' # MIS_CREDIT_LINE_ID: ' + A.MIS_CREDIT_LINE_ID ) AS [KEY]
,( A.MIS_CREDIT_LINE_BRANCH_ID + ' - ' + A.MIS_CREDIT_LINE_ID ) AS RESULT_1
,NULL AS RESULT_2
,NULL AS OUTSTANDING
FROM
STG_MIS_CREDIT_LINES_VALUE A
LEFT JOIN
STG_MIS_REG_CREDIT_LINES B ON A.REFERENCE_DATE = B.REFERENCE_DATE
AND A.MIS_BANK_ID = B.MIS_BANK_ID
AND A.MIS_CREDIT_LINE_BRANCH_ID = B.MIS_CREDIT_LINE_BRANCH_ID
AND A.MIS_CREDIT_LINE_ID = B.MIS_CREDIT_LINE_ID
WHERE
B.MIS_CREDIT_LINE_ID IS NULL
AND A.REFERENCE_DATE = '20131231'
如果我将 ROWCOUNT 参数更改为 2 或 0 或 100 或其他任何值,查询会再次快速运行(不到 1 秒)。
注意 1: 查询实际上返回 0 行(这对我来说没问题)。
注意 2: 我无法更改添加 TOP 1 语句的查询,因为我的是 ETL 软件,查询由固定的SET ROWCOUNT 1“组成”(出于技术原因,它是硬编码的)和企业用户编写的免费查询;像
SET ROWCOUNT 1
... SQL statement written by user ...
提前致谢。
尼古拉
[编辑]
执行计划(ROWCOUNT 1) http://pastebin.com/RambD7Aj
执行计划(ROWCOUNT 2) http://pastebin.com/cG4ngE4h
【问题讨论】:
-
当 ROWCOUNT 为 1 时,您的索引似乎没有被命中。您能否获得两个查询的执行计划?
-
添加了执行计划
-
我注意到 SET ROWCOUNT 1 和 SET ROWCOUNT 2 之间的奇怪行为。执行计划完全改变了...... :/ pastebin.com/RambD7Aj pastebin.com/cG4ngE4h
-
您发布的查询计划是估计计划。你认为你能掌握实际的计划吗?它将显示估计行数和实际行数之间的任何差异。您的第二个查询已经并行,可能是因为当您想要返回两行时,查询的成本最终超过了并行度的阈值。这导致了一个更快的计划,部分原因可能是因为它是并行的,但
rowcount 1查询不应该慢得多。对于预期返回 1 行的情况,应该有一个更快的计划。
标签: sql sql-server performance sql-server-2008-r2 rowcount