1

Microsoft サポートでチケットを開く前に、コミュニティを試してみようと思いました!

SQL 2008 R2 (開発者版、現在) で変更データ キャプチャを使用している開発中のアプリケーションがあります。特に複雑なクエリについては、クエリをストアド プロシージャにラップし、共通のパラメーターを公開して、クライアントでの複雑さを回避したいと考えました (通常の引数)...

いずれにせよ、スタンドアロン クエリとしての次のステートメントは、境界条件に関係なく約 3 ~ 5 秒で実行されますが、ストアド プロシージャとしてのまったく同じステートメントは 1.5 分に跳ね上がります。同じ結果を生成します。さらに、実行中の SP バージョンは、実行中にユーザー ID を数回切り替えるようです... また、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 で)。Stored Proceure として、1.5 分。.Net フレームワーク プロバイダー (System.Data.SqlClient) 経由のクエリとして、1.5 分。OleDb SQLNCLI10 プロバイダー経由のクエリとして、3 ~ 5 秒。Framework または OleDb を介した SP として、1.5 分。

何かご意見は?

4

1 に答える 1

0

私のお金は、キャッシュ内の不適切なクエリ プランにあります。プロシージャ キャッシュをフラッシュするか (ライブ システムではありません!)、SP で OPTION (再コンパイル) を使用して、それが役立つかどうかを確認してください。

于 2010-07-22T10:52:21.920 に答える