SQL 2008更改数据捕获查询性能问题(SP与直接查询)

时间:2010-06-15 07:34:40

标签: sql stored-procedures sql-server-2008-r2 change-data-capture

在我使用Microsoft支持打开机票之前,我想我会尝试社区!

我正在开发一个应用程序,我们在SQL 2008 R2中使用Change Data Capture(当前的开发人员版本)。对于一些特别复杂的查询,我们希望将查询包装到存储过程中,公开公共参数,以避免客户端的复杂性(通常的参数)......

在任何情况下,我们已经确定的是,作为一个独立的查询,以下语句将在大约3-5秒内运行,无论边界条件如何,而完全相同的语句,作为存储过程,跳转到1.5分钟产生相同的结果。此外,运行时的SP版本似乎在执行过程中多次切换用户身份...此外,在执行SP期间,CPU使用率激增。

有什么想法?

查询:

DECLARE @fromlsn BINARY(10),
    @tolsn   BINARY(10),
    @NodeID  varchar(6)
SET     @NodeID = '123456',
        @fromlsn = 0x000017E6000001AC0041,
        @tolsn = sys.fn_cdc_get_max_lsn()

DECLARE @min_lsn_TransactionDate BINARY(10),
        @min_TransactionDate smalldatetime

SELECT  @min_TransactionDate = MIN(TransactionDate)
FROM    cdc.fn_cdc_get_net_changes_dbo_tblOrders(sys.fn_cdc_increment_lsn(@fromlsn),@tolsn,'all with merge') 
WHERE   _NODEID_=@NodeId and __$operation<>1

SELECT  @min_lsn_TransactionDate = MIN(__$start_lsn)
FROM    cdc.dbo_tblOrders_CT with (nolock)
WHERE   _NODEID_=@NodeId
    AND TransactionDate=@min_TransactionDate

SELECT   Table1.TransactionDate
    ,Table1.OrderNumber
    ,Table1.SequenceNum 
    ,Table1.ItemNumber
    ,Table1.Quantity
    ,Table1.Price
    ,Table1.ExtPrice
FROM          cdc.fn_cdc_get_net_changes_dbo_tblOrders(sys.fn_cdc_increment_lsn(@fromlsn),@tolsn,'all with mask') Table1
WHERE   Table1._NodeID_=@NodeId
    AND (   Table1.__$operation=2
         OR (   Table1.__$operation=4  
            AND  ( sys.fn_cdc_is_bit_set(9,Table1.__$update_mask)=1 
                   OR sys.fn_cdc_is_bit_set(10,Table1.__$update_mask)=1 
                 )
             )
        )

相关的存储过程:

CREATE PROCEDURE testtesttest 
        @fromlsn BINARY(10),
        @tolsn   BINARY(10),
        @NodeID  varchar(10)
as 
DECLARE @min_lsn_TransactionDate BINARY(10),
        @min_TransactionDate smalldatetime

SELECT  @min_TransactionDate = MIN(TransactionDate)
FROM    cdc.fn_cdc_get_net_changes_dbo_tblOrders(sys.fn_cdc_increment_lsn(@fromlsn),@tolsn,'all with merge') 
WHERE   _NODEID_=@NodeId and __$operation<>1

SELECT  @min_lsn_TransactionDate = MIN(__$start_lsn)
FROM    cdc.dbo_tblOrders_CT with (nolock)
WHERE   _NODEID_=@NodeId
    AND TransactionDate=@min_TransactionDate

SELECT   Table1.TransactionDate
    ,Table1.OrderNumber
    ,Table1.SequenceNum 
    ,Table1.ItemNumber
    ,Table1.Quantity
    ,Table1.Price
    ,Table1.ExtPrice
FROM          cdc.fn_cdc_get_net_changes_dbo_tblOrders(sys.fn_cdc_increment_lsn(@fromlsn),@tolsn,'all with mask') Table1
WHERE   Table1._NodeID_=@NodeId
    AND (   Table1.__$operation=2
         OR (   Table1.__$operation=4  
            AND  ( sys.fn_cdc_is_bit_set(9,Table1.__$update_mask)=1 
                   OR sys.fn_cdc_is_bit_set(10,Table1.__$update_mask)=1 
                 )
             )
        )

执行SP的脚本:

DECLARE @fromlsn BINARY(10),
    @tolsn   BINARY(10),
    @NodeID  varchar(6)
SET     @NodeID = '123456',
        @fromlsn = 0x000017E6000001AC0041,
        @tolsn = sys.fn_cdc_get_max_lsn()

exec testtesttest @fromlsn,@tolsn,@NodeID

如上文所示,作为查询,需要3-5秒(在Management Studio中)。作为存储过程,1.5分钟。作为查询通过.Net框架提供者(System.Data.SqlClient),1.5分钟。作为OleDb SQLNCLI10提供程序的查询,3-5秒。通过Framework或OleDb作为SP,1.5分钟。

有什么想法?

1 个答案:

答案 0 :(得分:0)

我的钱将在缓存中的错误查询计划中。尝试刷新过程缓存(不是在实时系统上!)或使用SP中的OPTION(重新编译)来查看是否有帮助