Unter welchen Bedingungen würde SELECT by PRIMARY KEY langsam sein?

8

Verfolgen Sie einige DB-Leistungsprobleme in einer ziemlich typischen EclipseLink / JPA-Anwendung.

Ich sehe häufige Abfragen, die 25-100ms dauern. Dies sind einfache Abfragen, bei denen nur alle Spalten einer Tabelle ausgewählt werden, deren Primärschlüssel einem Wert entspricht. Sie sollten nicht langsam sein.

Ich schaue mir die Abfragezeit im postgres-Protokoll an, indem ich die log_min_duration_statement verwende, um den Netzwerk- oder Anwendungs-Overhead zu eliminieren.

Diese Abfrage ist nicht langsam, wird aber sehr oft verwendet.

Warum sollte die Auswahl * nach Primärschlüssel langsam sein? Ist das spezifisch für Postgres oder ist es ein generisches DB-Problem? Wie kann ich das beschleunigen? Im Algemeinen? Für Postgres?

Beispielabfrage aus dem PG-Protokoll:

%Vor%

Tabelle hat etwa 3,5 Millionen Zeilen.

Ich habe auch EXPLAIN und EXPLAIN ANALYSE für diese Abfrage ausgeführt, es macht nur einen Index-Scan.

    
Freiheit 28.07.2010, 16:36
quelle

5 Antworten

4

Wählen Sie * macht Ihre Datenbank härter arbeiten und als eine allgemeine Regel ist eine schlechte Praxis. Es gibt Tonnen von Fragen / Antworten auf Stackoverflow darüber reden.

Haben Sie versucht, * durch die Feldnamen zu ersetzen?

    
dave 28.07.2010, 16:44
quelle
2

Könnten Sie eine Art Sperrung bekommen? Welche Art von Sperren nehmen Sie bei der Durchführung dieser Abfragen vor?

    
djna 28.07.2010 16:41
quelle
2

Nun, ich weiß nicht viel über postgres SQL, also werde ich Ihnen einen Tipp für MS SQL Server geben, der anwendbar sein könnte.

MS SQL Server hat das Konzept eines "Cluster-Indexes", bei dem es sich um das physische Layout der Daten auf der Festplatte handelt. Es ist gut, das Feld zu verwenden, in dem Sie einen Bereich zwischen Werten suchen (meistens Datumsfelder). Es ist nicht viel nützlich, wenn Sie nach einem genauen Wert suchen (wie eine Primärschlüssel-Suche). Manchmal wird der Primärschlüsselindex jedoch versehentlich als gruppierter Index festgelegt. Dies führt dazu, dass ein Index nach einem Tabellenscan sucht.

    
James Curran 28.07.2010 16:42
quelle
1

Die Zeile ist ungewöhnlich groß oder enthält BLOBs und große Binärfelder?

Ist dies direkt über die Konsole oder wird diese Abfrage durch einige Datenzugriffs-API wie jdbc oder ADO.NET ausgeführt? Sie erwähnen JPA, das wie eine Datenzugriffs-API aussieht. Bei kurzen Abfragen wird die Datenzugriffs-API zu einem größeren Prozentsatz der Ausführungszeit - Erstellen des Befehls, Erstellen von Objekten zum Speichern der Zeilen und Zellen usw.

    
MatthewMartin 28.07.2010 17:17
quelle
1

select * ist fast immer eine sehr sehr schlechte Idee.

  1. Wenn sich die Reihenfolge der Felder ändert, wird Ihr Code beschädigt. Laut Kommentaren ist dies in Anbetracht der verwendeten Abstraktions-Bibliothek nicht wirklich wichtig.
  2. Sie geben wahrscheinlich mehr Daten aus der Tabelle zurück, als Sie tatsächlich möchten. Wenn Sie die gewünschten Felder auswählen, können Sie die Übertragungszeit sparen.

25ms ist ungefähr die untere Grenze, die Sie bei fast jeder Art von SQL-Abfrage sehen werden - das sind nur zwei Festplattenzugriffe! Möglicherweise möchten Sie nach Möglichkeiten suchen, die Anzahl der Abfragen zu verringern, anstatt die Abfrage zu optimieren.

    
Billy ONeal 28.07.2010 16:45
quelle