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

MySQL verwendet keine Indizes mit WHERE IN-Klausel?

Siehe Wie MySQL Indizes verwendet .

Überprüfen Sie auch, ob MySQL immer noch einen vollständigen Tabellenscan nachdem Sie etwa 2000 zusätzliche Zeilen zu Ihren user_metrics hinzugefügt haben Tisch. In kleinen Tabellen ist der Zugriff nach Index tatsächlich teurer (I/O-weise) als ein Tabellen-Scan, und der Optimierer von MySQL könnte dies berücksichtigen.

Entgegen meinem vorherigen Post , stellt sich heraus, dass MySQL auch einen kostenbasierten Optimierer verwendet , was sehr gute Neuigkeiten sind - vorausgesetzt, Sie führen Ihre ANALYZE aus mindestens einmal, wenn Sie glauben, dass die Datenmenge in Ihrer Datenbank repräsentativ ist der zukünftigen täglichen Nutzung.

Beim Umgang mit kostenbasierten Optimierern (Oracle, Postgres usw.) müssen Sie sicherstellen, dass Sie regelmäßig ANALYZE auf Ihren verschiedenen Tischen, wenn ihre Größe um mehr als 10-15% zunimmt. (Postgres erledigt dies standardmäßig automatisch für Sie, während andere RDBMS diese Verantwortung einem DBA, d. h. Ihnen, überlassen.) Durch statistische Analyse, ANALYZE hilft dem Optimierer dabei, eine bessere Vorstellung davon zu bekommen, wie viel I/O (und andere zugehörige Ressourcen, wie z. B. CPU, die z. Fehler beim Ausführen von ANALYZE kann zu sehr schlechten, manchmal katastrophalen Planungsentscheidungen führen (z. B. Millisekunden-Abfragen, die manchmal Stunden dauern, wegen schlecht verschachtelter Schleifen auf JOIN s.)

Wenn die Leistung nach dem Ausführen von ANALYZE immer noch unbefriedigend ist , dann können Sie das Problem normalerweise umgehen, indem Sie Hinweise verwenden, z. FORCE INDEX , während Sie in anderen Fällen vielleicht über einen MySQL-Fehler gestolpert sind (z. B. diesen älteren , was Sie hätte gebissen können, wenn Sie nested_set von Rails verwendet hätten ).

Nun, da Sie sich in einer Rails-App befinden , wird es umständlich (und macht den Zweck von ActiveRecord zunichte ), um Ihre benutzerdefinierten Abfragen mit Hinweisen auszugeben, anstatt weiterhin den ActiveRecord zu verwenden -generierte.

Ich hatte das in unserer Rails-Anwendung all erwähnt SELECT Abfragen fielen nach dem Wechsel zu Postgres unter 100 ms, während einige der komplexen Joins von ActiveRecord generiert wurden würde mit MySQL 5.1 aufgrund von verschachtelten Schleifen mit inneren Tabellenscans gelegentlich bis zu 15 Sekunden oder länger dauern, selbst wenn Indizes verfügbar waren. Kein Optimierer ist perfekt, und Sie sollten sich der Optionen bewusst sein. Andere potenzielle Leistungsprobleme, die Sie neben der Optimierung des Abfrageplans beachten sollten, sind Sperren. Dies liegt jedoch außerhalb des Bereichs Ihres Problems.