2008-11-21 9 views

Antwort

60

Angenommen, Sie fragen nach der allgemeinen "Indizierungshinweis" -Funktion in vielen Datenbanken, PostgreSQL bietet keine solche Funktion. Dies war eine bewusste Entscheidung des PostgreSQL-Teams. Ein guter Überblick darüber, warum und was Sie stattdessen tun können, finden Sie here. Die Gründe sind im Grunde, dass es ein Performance-Hack ist, der dazu neigt, später bei der Änderung der Daten mehr Probleme zu verursachen, während der Optimierer von PostgreSQL den Plan basierend auf den Statistiken neu bewerten kann. Mit anderen Worten, was heute ein guter Abfrageplan sein könnte, wird wahrscheinlich kein guter Abfrageplan für alle Zeiten sein, und Indexhinweise erzwingen einen bestimmten Abfrageplan für alle Zeiten.

Als sehr stumpfer Hammer, der zum Testen nützlich ist, können Sie die Parameter enable_seqscan und enable_indexscan verwenden. Siehe:

Dies sind nicht geeignet für die laufende Produktion Verwendung. Wenn Sie Probleme mit der Auswahl des Abfrageplans haben, sollten Sie the documentation for tracking down query performance issues sehen. Stellen Sie nicht nur enable_ params und gehen Sie weg.

Wenn Sie keinen guten Grund haben, den Index zu verwenden, trifft Postgres möglicherweise die richtige Wahl. Warum?

  • Bei kleinen Tabellen ist es schneller, sequenzielle Scans durchzuführen.
  • Postgres verwendet keine Indizes, wenn Datentypen nicht richtig übereinstimmen, Sie müssen möglicherweise geeignete Umwandlungen einfügen.
  • Ihre Planungseinstellungen können Probleme verursachen.

Siehe auch this old newsgroup post.

+4

Einverstanden, Postgres Erzwingen es Ihre Art und Weise Sie in der Regel zu tun, bedeutet, habe es falsch gemacht. 9/10 Mal wird der Planer alles übertreffen, was man sich vorstellen kann. Das andere Mal ist es, weil du es falsch gemacht hast. –

+0

Ich denke, es ist eine gute Idee für die Überprüfung wirklich Operator Klassen Ihres Index halten. – metdos

+2

Ich hasse es, eine alte Frage neu zu beleben, aber ich sehe oft in Postgres-Dokumentation, Diskussionen und hier, aber gibt es ein verallgemeinertes Konzept für was für eine * kleine Tabelle *? Ist es etwa 5000 Reihen oder 50000 usw.? – waffl

0

Das PostgresPlus Advanced Server-Produkt von EnterpriseDB unterstützt die Oracle-Hintsyntax, obwohl dieses Produkt nicht kostenlos ist.

9

Die Frage an sich ist sehr ungültig. Das Erzwingen (zB durch enable_seqscan = off) ist eine sehr schlechte Idee. Es kann nützlich sein, zu überprüfen, ob es schneller ist, aber Produktionscode sollte niemals solche Tricks verwenden.

Stattdessen erklären Sie bitte analysieren Ihrer Abfrage, lesen Sie es und finden Sie heraus, warum PostgreSQL schlecht (Ihrer Meinung nach) Plan wählt.

Es gibt Tools im Internet, die beim Lesen helfen, analysieren Ausgabe - einer von ihnen ist explain.depesz.com - von mir geschrieben. Eine andere Möglichkeit ist es, #postgresql channel auf freenode irc-Netzwerk zu verbinden, und mit den Leuten dort zu sprechen, um Ihnen zu helfen - da die Optimierung der Abfrage nicht eine Frage von "Frage eine Frage, Antwort ist glücklich sein" ist. es ist mehr wie eine Konversation, mit vielen Dingen zu überprüfen, viele Dinge zu lernen.

+0

Die Mailinglisten sind auch ein ausgezeichneter Ort, um Hilfe zu bekommen. – jpmc26

44

Wahrscheinlich die einzige gültige Grund für die Verwendung

set enable_seqscan=false 

ist, wenn Sie Abfragen gerade schreiben und wollen schnell sehen, was die Abfrage-Plan würde tatsächlich in der Tabelle gab es große Mengen von Daten sein (s). Oder natürlich, wenn Sie schnell bestätigen müssen, dass Ihre Abfrage keinen Index verwendet, einfach weil der Datensatz zu klein ist.

+36

Diese kurze Antwort gibt tatsächlich einen guten Hinweis für Testzwecke – dwery

+2

Niemand beantwortet die Frage! –

+0

@IvailoBardarov Der Grund all diese anderen Vorschläge sind hier, weil PostgreSQL diese Funktion nicht hat; Dies war eine bewusste Entscheidung der Entwickler, basierend auf ihrer typischen Verwendung und den damit verbundenen langfristigen Problemen. – jpmc26

7

Manchmal kann PostgreSQL nicht die beste Auswahl an Indizes für eine bestimmte Bedingung treffen. Nehmen wir zum Beispiel an, es gibt eine Transaktionstabelle mit mehreren Millionen Zeilen, von denen es mehrere hundert für einen bestimmten Tag gibt, und die Tabelle hat vier Indizes: transaction_id, client_id, date und description. Sie möchten die folgende Abfrage ausführen:

SELECT client_id, SUM(amount) 
FROM transactions 
WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND 
     description = 'Refund' 
GROUP BY client_id 

PostgreSQL können wählen, um den Index transactions_description_idx statt transactions_date_idx, die stattdessen mehrere Minuten unter, um die Abfrage führen kann von weniger als einer Sekunde. Wenn dies der Fall ist, können Sie den Index auf Datum mit Gewalt durch die Bedingung wie folgt fudging:

SELECT client_id, SUM(amount) 
FROM transactions 
WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND 
     description||'' = 'Refund' 
GROUP BY client_id 
0

Es gibt eine Zecke Postgres schieben ein seqscan bevorzugen eine OFFSET 0 in der Unterabfrage Hinzufügen

Diese ist praktisch für die Optimierung von Anfragen, die große/riesige Tabellen verknüpfen, wenn Sie nur nach den ersten/letzten Elementen suchen.

Nehmen wir an, Sie suchen nach den ersten/letzten 20 Elementen mit mehreren Tabellen mit 100k (oder mehr) Einträgen, keine Punktbildung/Verknüpfung aller Abfragen über alle Daten, wenn das, was Sie suchen, in der erste 100 oder 1000 Einträge. In diesem Szenario ist es zum Beispiel mehr als 10x schneller, einen sequenziellen Scan durchzuführen.

siehe How can I prevent Postgres from inlining a subquery?