基本的にあるテーブルから別のテーブルに値をコピーする変換ユーティリティがあります。しばらくは問題なく機能していましたが、ある顧客で奇妙な問題に遭遇しました。彼らはユーティリティで 150 万件のレコードを処理しましたが、現在は完全に停止しています。
VB.Net からストアド プロシージャを呼び出すと、SqlCommand がタイムアウトするまでハングします。Management Studio から同じ sproc を呼び出すと、即座に実行されます。SqlCommand の私の VB.Net コードは次のとおりです (insertConn
以前に定義されて開かdr
れており、完全に異なる SqlConnection および SqlCommand インスタンスから前の手順で設定された SqlDataReader です):
Dim conn As New SqlConnection("connection string here")
Dim insertConn As New SqlConnection("connection string here")
Dim dr As SqlDataReader = Nothing
Dim readCommand As New SqlCommand("my query here", conn)
conn.Open()
insertConn.Open()
...
dr = readCommand.ExecuteReader()
...
While dr.Read()
Using insertCommand = New SqlCommand("dmDocumentFieldInsert", insertConn)
insertCommand.CommandType = CommandType.StoredProcedure
insertCommand.Parameters.AddWithValue("@DocumentKey", dr("DocumentKey"))
insertCommand.Parameters.AddWithValue("@FieldId", "TITLE")
insertCommand.Parameters.AddWithValue("@FieldValue", dr("DocumentTitle"))
insertCommand.ExecuteNonQuery()
End Using
End While
SQL Server を再起動してロックをクリアし、sproc を再コンパイルし、SqlCommand と SqlConnection のタイムアウトをすべて無駄に増やしてみました。
パラメータに追加されるデータを確認しましたが、それは有効なデータです...同じデータでsprocを手動で呼び出すと、正常に動作します。
私はもともとUsing
ブロックを使用していませんでしたが、それを変更して、破棄/クローズされていないリソースの問題があるかどうかを確認しました。ユーティリティのメモリ使用量は約 5MB で推移しているため、メモリの問題はないようです。
解決策として次に何を試すべきかについて提案がある人はいますか?
EDITコメントリクエストごとにループと初期化コードを追加
編集統計を更新し、テーブルのインデックスを再構築しましたが、変更はありません。
EDITデータがコピーされるテーブルには 3 つのインデックスがあります (dmDocumentField)。3 つのインデックスをすべて無効にすると、sproc は完全に実行されますが、インデックスが存在する場合よりもはるかに遅くなります。それらのいずれかを有効にすると、ユーティリティは最大で数百のレコードを通過し、sproc で同じタイムアウトで終了します。インデックスを削除して再作成しても効果はありません。テーブル構造とインデックスは次のとおりです。
CREATE TABLE [dbo].[dmDocumentField](
[FieldKey] [bigint] IDENTITY(1,1) NOT NULL,
[DocumentKey] [char](36) NOT NULL,
[FieldId] [varchar](10) NOT NULL,
[FieldValue] [varchar](255) NOT NULL,
CONSTRAINT [PK_dmDocumentField] PRIMARY KEY NONCLUSTERED
(
[FieldKey] ASC,
[DocumentKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
インデックス (PK 以外):
CREATE NONCLUSTERED INDEX [dmDocumentField_DocumentKey] ON [dbo].[dmDocumentField]
(
[DocumentKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
.
CREATE NONCLUSTERED INDEX [dmDocumentField_DocumentKey_IFieldId_IFieldValue] ON [dbo].[dmDocumentField]
(
[DocumentKey] ASC
)
INCLUDE ( [FieldId],
[FieldValue]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]