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
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
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ohne Ausführungsplan wir können nur erahnen, was passiert.
Ich würde anfangen, aus:
document
Tabelle hat (aber es ist schwer zu glauben, dass die Aktualisierung von Indizes nimmt eine solche Zeit).Alle diese sichtbar sein soll Ausführungsplan.
Ein weiterer Grund könnte sein, dass die SQL-engine hat einen plan für die Ausführung
SELECT
Abfrage und anderes fürUPDATE
Abfrage...UPDATE
Nach einem Blick in die Indizes.
Meiner Meinung nach 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_
ist völlig falsch.Es gehören eine Menge von Spalten, die Aktualisierung langsam.
Versuchen, es zu entfernen oder ersetzen Sie es mit
CLUSTERED
index aufstate
Spalte.CLUSTERED
index** (direkten Zugang), um alle Spalten des Datensatzes ohne extra liest.Wahrscheinlich es sollte kombiniert werden mit einer der anderen Indizes begann mit
state
Spalte -- ich gehe davon ausstate
hat nur ein paar Werte.Leider bin ich nicht in der Lage zu interpretieren, Ausführung plan im text-format.
danke für deine Antwort. Das format der Ausführung plan können Sie Lesen? vielleicht kann ich es ändern, um ein anderes format. Ich werde versuchen, Sie zu entfernen, alle Indizes und neue zu schaffen, ohne das Vertrauen in die MSSQL-Datenbank-optimizer erstellt Indizes 😉
Bild ist die easiests, jedoch ist es nicht der Fall. Ich sah, dass der plan als XML-Datei abgespeichert, aber ich bin nicht sicher, ob ich interpretieren könnte es besser. Schauen Sie auf Ihren plan, die Suche nach IO-Kosten, Anzahl der Datensätze und bytes zu Lesen, prüfen Sie, ob Sie nicht haben, table-scans (in der Regel schlechte Sache), index-scans oder ENTFERNEN lookups -- dies sind die typischen Flaschenhälse.
InformationsquelleAutor Grzegorz Gierlik
Wahrscheinlich haben Sie Indizes auf der Tabelle Dokument. Indizes stellen Sie wählt schneller, aber langsame Aktualisierung/inset/löschen Betrieb.
Entfernen Sie unnötige Indizes.
Es ist wahrscheinlich das fehlen von Indizes, verursacht dies, als die Existenz einer Menge.
Wenn ich die Tabelle erstellt ich lief einige tests, protokolliert jede Aussage mit dem profiler und verwendet die SQL Server DatabaseOptimizer, um meine Indizes.
warum "nur einen einzigen index"? Sind Sie der Annahme, dass nur eine einzige Spalte Indizes existieren? Was ist, wenn
State
ist Teil des viele Indizes? Ohne den plan kennen wir nicht, aber ich glaube nicht, dass man sagen kann, dass dies nur auf einen index.hi Aaron. Ich habe das XML-Executionplan schon. Vielleicht kannst du es dir ansehen? seine grafische und sollte leichter zu Lesen. hier ist der Link agail: Edit 2: Jetzt habe ich eine grafische Ausführung-plan : Execution-plan: link Execution-plan Index der Update-details: link
InformationsquelleAutor semao
Ich hatte dieses problem einmal auf SQL Server 2008 und SQL Server 2014 Verbindungsserver. Ein Abhilfe für mich war es, speichern Sie die "Select" - Ergebnisse in eine temporäre Tabelle und verwenden Sie diese zu tun, das update eher tun, die komplexe Abfragen und das update auf einmal.
In deinem Fall wäre dies:
InformationsquelleAutor nbougiou