6

多くの行 (最大数百万行) を含む SQL Tabe "Document" があります。

Select-Statement を実行すると、約 0.5 秒かかります。しかし、まったく同じ WHERE 句を使用して Update を実行すると、影響を受ける行の量に応じて、約 20 ~ 50 秒かかります。

これが私のステートメントです。

//選択する

SELECT * FROM Document 
WHERE (State=20 OR State=23) AND 
LetterClosed IS NOT NULL AND 
TYPE=0 AND
SendLetter=1

//アップデート

UPDATE Document set State=32 
WHERE (State=20 OR State=23) AND 
LetterClosed IS NOT NULL AND 
TYPE=0 AND
SendLetter=1

OR-Mapper は、次のようにこの update-statement を内部的にデータベースに送信します。

exec sp_executesql N'Update
Document
SET
    State=@p4
WHERE
(
  (
    (
      (Document.State = @p0 OR Document.State = @p1) 
      AND Document.LetterClosed IS NOT NULL
    ) 
    AND Document.Type = @p2
  ) 
  AND Document.SendLetter = @p3
)'
,N'@p0 int,@p1 int,@p2 int,@p3 bit,@p4 int',@p0=20,@p1=23,@p2=0,@p3=1,@p4=32

問題は、LightSpeed(C# のデータベース OR-Mapper) から 30 秒後に Timeout-Exception が発生することです。

ここで誰か助けてくれませんか?

編集:

これは、SQL-Server によって自動的に作成されたインデックスです。

CREATE NONCLUSTERED INDEX [_dta_index_Document_9_133575514__K42_1_2_3_4_5_6_7_8_9_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_] ON [Document] 

(
    [State] ASC
)
INCLUDE ( 
[Id],[DocumentId],[SendLetter],[SendFax],[Archive],[Crm],[Validation],[CreationDate],[PageCount],
[InformationLetter],[TermsOfDelivery],[DeliveryTypeNo],[SeparateDelivery],[FormName],[FormDescription],[TemplateFileName],[RecipientType],
[HealthInsuranceNo],[FamilyHealthInsuranceNo],[PensionInsuranceNo],[EmployerCompanyNo],[RecipientName1],[RecipientName2],[RecipientName3],
[RecipientStreet],[RecipientCountryCode],[RecipientZipCode],[RecipientCity],[RecipientFaxNo],[AuthorId],
[AuthorName],[AuthorEmailAddress],[CostcenterDepartment],[CostcenterDescription],[MandatorNo],[MandatorName],[ControllerId],
[ControllerName],[EditorId],[EditorName],[StateFax],[Editable],[LetterClosedDate],[JobId],[DeliveryId],[DocumentIdExternal],[JobGroupIdExternal],
[GcosyInformed]) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
go

CREATE NONCLUSTERED INDEX [_dta_index_Document_9_133575514__K2_1_46] ON [Document] 
(
    [DocumentId] ASC
)
INCLUDE ( [Id],
[JobId]) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
go

CREATE NONCLUSTERED INDEX [_dta_index_Document_9_133575514__K46_K2] ON [Document] 
(
    [JobId] ASC,
    [DocumentId] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
go



CREATE NONCLUSTERED INDEX [Document_State_Id] ON [Document] 
(
    [State] ASC,
    [Id] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
go

CREATE NONCLUSTERED INDEX [Document_State_CreationDate] ON [Document] 
(
    [State] ASC,
    [CreationDate] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
go

編集 2: グラフィカルな実行計画があります: 実行計画: https://skydrive.live.com/redir?resid=597F6CF1AB696567!444&authkey=!ABq72SAWXOoAXfI

実行計画インデックス更新の詳細: https://skydrive.live.com/?cid=597f6cf1ab696567&id=597F6CF1AB696567%21445&sff=1&authkey=!ADDPWvxB2JLLvWo

この SQL-Update の実行には約 35 秒かかりました。通常、この更新には 0.3 秒しかかかりません。別のプロセスがこのプロセスをブロックしたようです。この更新の途中で開始され、選択実行が終了するまで更新が完了するまで待っていた他の選択をいくつか見ました。

したがって、インデックス自体は正しいようです (通常は 0,3 秒の実行)。すべての選択 (java/jtds、php、.net から) は分離レベル read-committed (デフォルト) です。インデックス更新中のこのブロックを回避するために、すべての選択をコミットされていない読み取りに変更すると、ここで役立ちますか?

ありがとうトビ

4

3 に答える 3

3

実行計画がなければ、何が起こるかを推測することしかできません。

私はから始めます:

  1. テーブルにいくつのインデックスがあるかを確認しますdocument(ただし、インデックスの更新にそれほど時間がかかるとは信じがたいです)。
  2. 更新時にトリガーが実行されているかどうかを確認します。

これらはすべて実行計画に表示される必要があります。

もう 1 つの理由は、SQL エンジンがクエリに対して 1 つの実行プランを持ち、SELECTクエリに対して別の実行プランを持っていることUPDATEです...

アップデート

インデックスを調べた後。

私の意見では、インデックス_dta_index_Document_9_133575514__K42_1_2_3_4_5_6_7_8_9_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_は完全に間違っています。

更新が遅くなる可能性のある多くの列が含まれています。

それを削除するか、列のCLUSTEREDインデックスに置き換えてみてください。index* include* (直接アクセス可能) は、追加の読み取りなしでレコードのすべての列にアクセスできます。stateCLUSTERED

stateおそらく、列で始まる他のインデックスの1つと組み合わせる必要があります-stateいくつかの値しかないと思います。

残念ながら、実行計画をテキスト形式で解釈することはできません。

于 2013-01-11T09:28:06.967 に答える
2

おそらく、テーブル Document にインデックスがあります。インデックスを使用すると、選択が高速になりますが、更新/挿入/削除操作が遅くなります。

不要なインデックスを削除してみてください。

于 2013-01-11T09:14:37.147 に答える