予約に使用されるトランザクションデータベース...
私たちのベンダーは、#temptablesを@tablevariablesに置き換えるように依頼されました(コンパイルロックが重いため)。代わりに、SPIDを列として追加する実際のテーブルに置き換えて、ストアドプロシージャが適切な行でのみ機能するようにしました。
この操作方法にリスクはありますか?すべてのトランザクションが独自のトランザクション内に分離される前に...このテーブルを大量にロックしてしまうのではないかと心配していましたが、SQLは行レベルのロックを使用しているため、これ以上のロックは作成されません。
SQL Serverバージョン:2016 Enterprise-13.0.5216.0
CREATE TABLE dbo.qryTransactions (
ID int IDENTITY (0,1) NOT NULL CONSTRAINT pk_qryTransactions PRIMARY KEY CLUSTERED,
spid int NOT NULL,
OrderID int,
ItemID int,
TimeTransactionStart datetime,
TimeTransactionEnd datetime,
...other fields
)
CREATE INDEX idx_qryTransactions_spidID ON qryTransactions (spid, ID) INCLUDE (ItemID, OrderID, TimeTransactionStart, TimeTransactionEnd)
コメントブロックに収まりきらないぐらい少しまとまりがあり、レイの回答に応じてOPが作成したコメントを強調したい場合:
1分間少し接していきます...このシナリオで何が起こるかについては、Sybase ASEです...
OPの問題に戻ります(子プロシージャのコンパイルロック)...
@@ SPIDで単一の永続テーブルを使用してセッション間で行を区別するという考えは...そこにあります... yuck;繰り返し発生する問題:
私は戻って根本的な問題(子プロシージャの再コンパイルロック)を(再)調査し、上記のコンパイルロックを削減(排除?)する方法があるかどうかを確認したいと思います。 [残念ながら、これらの問題に関する私のSQL Serverの知識は... NULL ...なので、SQL Serverコンパイラの専門家からの入力に興味があります。]
@@SPID
をこのように使用すると、問題が発生するようです。
セッションIDは頻繁に再利用されます。ユーザー接続がログアウトするとすぐに、そのセッションIDは再び使用できるようになり、接続を試みる次のセッションで使用される可能性があります。
少なくともある程度の信頼性で機能させるには、同じ@@SPID
を持つテーブルから前の行を削除するログイントリガーが必要です。その場合、@@SPID
列を使用してテーブルが大量にロックされる可能性があります。
SQL Serverは実際に行ロックを使用しますが、ページロックとテーブルロックも使用します。もちろん、適切なインデックス付けによってそれを軽減できるかもしれませんが、これは私にはまだアンチパターンのように見えます。
ストアドプロシージャが、影響を受けるテーブルへのアクセスに使用されるonlyメソッドである場合、sp_getapplock
を介してアプリケーションロックを使用し、基本的にシリアル化することで調査できます。関連部品へのアクセス。 sp_getapplockのドキュメントは here です。 Erik Darling はそれについて興味深い投稿をしています here 。
はい、リスクはあります。行ロックを使用してSQLを信頼するのは簡単です。たとえば、挿入と削除では少なくともページロックを使用すると確信しています。 SQLエンジンは、いくつかの要因に基づいてロックの種類を選択しますが、これらの要因には「自分の意見」は含まれません。一時テーブルをテーブル変数に変更するような包括的なソリューションは、一般的にも悪い考えです。テーブル変数は状況によっては非常に役立ちますが、制限とパフォーマンスの問題があります。私はほとんどの状況で一時テーブルを好みます。特に、テーブルが数十行を超える場合。システムに「重いコンパイルロック」が発生した理由と、それによってパフォーマンスがどのように低下したかをベンダーに説明する必要があります。あなたが見ているときはいつでも、あなたはある種の「重いロック」を見つけるでしょう。それは必ずしもロックが問題であることを意味しません。 @@ SPIDに関するMaxのコメントも重要です。さらに、トランザクションモデルとエラー処理は大きな問題になる可能性があります。システムでデッドロックまたは入力データ品質の問題が発生した場合、標準エラー処理により、qryTransactionsテーブルが適切にリセットされずにセッションが終了する可能性があります。 IMOは、元の問題に対する間違ったソリューションアプローチです。