SET ROWCOUNT 1性能问题

时间:2014-05-06 14:20:04

标签: sql sql-server performance sql-server-2008-r2 rowcount

我遇到了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

1 个答案:

答案 0 :(得分:1)

在不查看执行计划的情况下无法肯定地说,但听起来就像您第一次添加SET ROWCOUNT 1时尝试创建不使用索引的新执行计划,当您再次重新运行时它使用正确执行计划。

以下是一些值得尝试的事情。

  • OPTION (RECOMPILE)添加到您的查询中。
  • 尝试将SET ROWCOUNT 1替换为SELECT TOP 1
  • 查看两个查询的执行计划。
  • 添加ROW_NUMBER()并将您的查询转换为带有where子句的派生表,其中rn = 1