0

Wir haben eine Tabelle, die nur über 62k Zeilen hat. Wir führen eine sehr einfache Löschabfrage auf sie, die 45 Minuten dauert abzuschließen:Postgres langsam laufende Abfrage löschen

DELETE FROM myTable WHERE createdtime < '2017-03-07 05:00:00.000' 

Dinge, die wir versucht haben:

1- einen Index für Timestamp-Spalte hinzugefügt, die nicht geholfen haben.

2- Entfernen Sie die Zeilen in Chargen von 20 oder 50 mit einer Funktion, die immer noch sehr langsam war.

3- Dropped alle Fremdschlüssel-Constraints Referenzierung dieser Tabelle und eine eigene Primärschlüsselbedingung, die Hilfe tat und die Zeit auf wenige Sekunden reduziert, aber wir können diese auf unserer Produktionsdatenbank nicht sicher tun, wie es die verriegelt Tabellen und verhindern Lese- und Schreibvorgänge, während die Transaktion ausgeführt wird.

Ich weigere mich zu glauben, dass es normal ist, dass diese Abfrage so lange dauert. Irgendwelche Vorschläge werden geschätzt.

+5

'Dropped alle Fremdschlüssel-Constraints Referenzierung diese table' diese FK die Sie haben Indizes sie zu unterstützen (auf der * andere * Tabelle)? – joop

+0

Was er gesagt hat. Offensichtlich wird die Zeit damit verbracht, die FK-Bedingungen nachzuschlagen. – paqash

+0

Leistungsfragen sollten EXPLAIN ANALYSE und einige Informationen über Tabellengröße, Index, aktuelle Zeitleistung, Wunschzeit usw. enthalten. Langsam ist ein relativer Begriff und wir brauchen einen echten Vergleichswert. MySQL Bitte lesen Sie auch [How-to-Ask] (http://stackoverflow.com/help/how-to-ask) – e4c5

Antwort

3

... Dropped all the foreign key constraints referencing this table

Stellen Sie sicher, diese FK die haben Indizes sie zu unterstützen (auf der anderen Tabelle). Wenn Sie löschen, muss der (kaskadierende) FK alle FK-Spalten aus anderen Tabellen überprüfen, die sich auf diese Zeile beziehen könnten.


- Beispiel:

CREATE TABLE team(
     id INTEGER NOT NULL PRIMARY KEY 
     , name varchar UNIQUE 
     ); 

CREATE TABLE player(
     id INTEGER NOT NULL PRIMARY KEY 
     , team_id integer REFERENCES team(id) 
     , name varchar UNIQUE 
     ); 

Wenn nun ein team gelöscht wird, wird die FK-Einschränkung zu überprüfen, ob es irgendwelche Spieler, die auf diese team_id beziehen. (Und Kaskade sachgemässer) In diesem Fall wird ein unterstütz Index auf der FK wird das DBMS helfen:

CREATE index ON player(team_id); 

hilft, ist ein bisschen zu hier schwach. Ein unterstützender Index ist für jeden nicht trivialen Fall unbedingt erforderlich. (Auch wenn der FK-Einschränkung hat ON UPDATE NO ACTION ON DELETE NO ACTION als Aktion, so scheint es)

+0

Nur für jedermanns Vorteil, obwohl meine FKs alle auf ON UPDATE NO ACTION ON LÖSCHEN NO ACTION eingestellt waren, schien diese Überprüfung sowieso stattgefunden zu haben, was zu der langsam laufenden Abfrage führte, was für mich überraschend ist. – infiniteLoop

+0

@infiniteLoop: Das ist überhaupt nicht überraschend, da die Datenbank sicherstellen muss, dass kein Spieler in der Umgebung das "Team" enthält, das Sie löschen. Und diese Suche erfolgt im Wesentlichen mit einem 'select * from player wobei team_id = ...' wenn kein Index vorhanden ist, wird ein Seq Scan in der player Tabelle benötigt. –

+0

@a_horse_with_no_name: Aber warum sollte es überprüft werden, ob es nicht plant, die untergeordneten Zeilen zu entfernen, die der zu löschenden Elternzeile zugeordnet sind? – infiniteLoop