SQL-Update ist sehr langsam (etwa 20-50sec), Auswählen, dauert weniger als 1 Sekunde

Ich habe eine SQL-Tabe "Dokument" enthält eine Menge von Zeilen (bis zu einigen Millionen).

Wenn ich ausführen einer Select-Anweisung, es dauert etwa 0,5 Sekunden.
Aber wenn ich ausführen ein Update mit der gleichen WHERE-Klausel es dauert etwa 20 bis 50 Sekunden, abhängig von der Menge der betroffenen Zeilen.

Hier sind meine Statements.

//Wählen Sie

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

//Update

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

Den OR-Mapper intern senden Sie dieses update-Anweisung wie folgt in die Datenbank:

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

Das problem ist, dass ich eine Timeout-Ausnahme nach 30 Sekunden aus meiner LightSpeed(Datenbank OR-Mapper in c#).

Könnte mir jemand helfen hier?

Edit:

Und dies sind unsere Indizes automatisch erstellt 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

Edit 2:
Nun habe ich eine grafische Ausführung-plan :
Execution-plan: https://skydrive.live.com/redir?resid=597F6CF1AB696567!444&authkey=!ABq72SAWXOoAXfI

Execution-plan Index der Update-details: https://skydrive.live.com/?cid=597f6cf1ab696567&id=597F6CF1AB696567%21445&sff=1&authkey=!ADDPWvxB2JLLvWo

Diese SQL-Update dauerte etwa 35 Sekunden ausgeführt werden. Normalerweise wird dieses Update dauert nur 0,3 Sekunden. Es scheint, dass ein anderer Prozess blockiert diese. Ich sah einige andere wählt, die begann in der Mitte dieses update und wartete, bis das update fertig war, bis Sie fertig wählen-Ausführung.

So scheint es, dass der index selbst korrekt ist (in der Regel 0,3 s-Ausführung).
Alle selects (von java/jtds, php, .net) sind isolation level read committed (Standard). Würde es mir helfen, hier alles zu verändern, was der wählt, read uncommitted um dies zu vermeiden, blockiert während index-update?

Dank
Tobi

Wie viele Zeilen zurückgegeben werden, die von der SELECT? Was DBMS verwenden Sie? (Ich denke, SQL-Server aus der sp_executesql) Können Sie die CREATE TABLE Aussage (und die vorhandenen Indizes)? Hinzufügen Sie können den Ausführungsplan?
Wir sind mit MSSQL-Server 2005. Ich werde versuchen, nach der execution-plan und die create-Anweisung.
Auch keine Indizes für die Tabelle, die Sie tun müssen, um eine genaue Antwort, es werden entweder zu viele Indizes, oder zu wenige, oder Sie können einfach zu ändern ein wenig. Wenn Sie den Ausführungsplan in SSMS es kann auch empfehlen, einen index beschleunigen.
Sie haben die gleiche Ausführung mal, wenn Sie Abfragen ausführen, die von Ihrer app und SSMS?
In der Regel Menschen Anhängen screenshot mit plan, aber könnte es nicht für große Pläne.

InformationsquelleAutor Tobias Koller | 2013-01-11

Schreibe einen Kommentar