在我向 Microsoft 支持开票之前,我想我会尝试社区!
我有一个正在开发中的应用程序,我们在 SQL 2008 R2(目前是开发人员版)中使用变更数据捕获。对于一些特别复杂的查询,我们希望将查询包装到存储过程中,暴露公共参数,以避免客户端的复杂性(通常的参数)......
在任何情况下,我们已经确定以下语句作为独立查询将在大约 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 分钟。
有什么想法吗?