Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Geschwindigkeit des Schlüsselworts IN in MySQL/PostgreSQL

In PostgreSQL hängt genau das, was Sie hier erhalten, von der zugrunde liegenden Tabelle ab, daher sollten Sie EXPLAIN ANALYZE auf einige Beispielabfragen für eine nützliche Teilmenge Ihrer Daten anwenden, um genau herauszufinden, was der Optimierer tun wird (stellen Sie sicher, dass die Tabellen Sie rennen gegen wurden auch ANALYSIERT). IN kann auf verschiedene Arten verarbeitet werden, und deshalb müssen Sie sich einige Beispiele ansehen, um herauszufinden, welche Alternative für Ihre Daten verwendet wird. Es gibt keine einfache allgemeine Antwort auf Ihre Frage.

Was die spezifische Frage betrifft, die Sie in Ihrer Überarbeitung hinzugefügt haben, hier ein Beispiel für die beiden Abfragepläne, die Sie gegenüber einem trivialen Datensatz ohne beteiligte Indizes erhalten:

postgres=# explain analyze select * from x where s in ('123','456');
 Seq Scan on x  (cost=0.00..84994.69 rows=263271 width=181) (actual time=0.015..1819.702 rows=247823 loops=1)
   Filter: (s = ANY ('{123,456}'::bpchar[]))
 Total runtime: 1931.370 ms

postgres=# explain analyze select * from x where s='123' or s='456';
 Seq Scan on x  (cost=0.00..90163.62 rows=263271 width=181) (actual time=0.014..1835.944 rows=247823 loops=1)
   Filter: ((s = '123'::bpchar) OR (s = '456'::bpchar))
 Total runtime: 1949.478 ms

Diese beiden Laufzeiten sind im Wesentlichen identisch, da die eigentliche Verarbeitungszeit durch den sequentiellen Scan über die Tabelle dominiert wird; Durch mehrmaliges Ausführen wird angezeigt, dass der Unterschied zwischen den beiden unter der Fehlerspanne von Lauf zu Lauf liegt. Wie Sie sehen können, wandelt PostgreSQL den IN-Fall in die Verwendung seines ANY-Filters um, der immer schneller ausgeführt werden sollte als eine Reihe von ORs. Auch dieser triviale Fall ist nicht unbedingt repräsentativ für das, was Sie bei einer ernsthaften Abfrage sehen werden, bei der Indizes und dergleichen involviert sind. Unabhängig davon sollte das manuelle Ersetzen von INs durch eine Reihe von OR-Anweisungen niemals schneller sein, da der Optimierer weiß, was hier am besten zu tun ist, wenn er über gute Daten verfügt, mit denen er arbeiten kann.

Im Allgemeinen kennt PostgreSQL mehr Tricks zum Optimieren komplizierter Abfragen als der MySQL-Optimierer, aber es hängt auch stark davon ab, dass Sie dem Optimierer genügend Daten zur Verfügung gestellt haben, mit denen er arbeiten kann. Die ersten Links im Abschnitt "Leistungsoptimierung" des PostgreSQL-Wikis behandeln die wichtigsten Dinge, die erforderlich sind, um gute Ergebnisse mit dem Optimierer zu erzielen.