In High Performance MySQL auf Seite 159 geht es darum, komplexe Abfragen in einfache aufzuteilen:
Konvertieren
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag='mysql';
Zu
SELECT * FROM tag WHERE tag='mysql';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id in (123,456,567,9098,8904);
Und sozusagen den eigentlichen Beitritt zu Ihrer Bewerbung.
Meine Frage ist, ob dies immer noch eine so gute Idee ist, wenn die letzte Abfrage eine where-Klausel mit einigen tausend IDs enthält, mit denen sie übereinstimmen muss (die eigentliche Tabelle selbst enthält ungefähr 500.000 Einträge).
Was ich meine ist, wird es eine große Strafe für eine Anfrage wie geben
SELECT * FROM post WHERE post.id in (123,456,567, ... <a few thousand IDs here> ... ,9098,8904);
anstelle der obigen join-Anweisung? Wäre es hilfreich, diese Logik auf gespeicherte Prozeduren in der Datenbank zu verschieben (unter Berücksichtigung der Tatsache, wie schlecht gespeicherte Prozeduren in MySQL implementiert sind)?
mysql
performance
myisam
Dexter
quelle
quelle
IN
Klausel mit ein paar tausend IDs ausführen müssenpost
Tabelle, ist dieser Beitrag wie in der Adresse? Wenn ja, könnten Sie eine Abfrage basierend auf der Postleitzahl oder nach Stadt ausführenpost.id
von dort die entsprechenden erhalten und dieIN
Klausel in der letzten Abfrage verwenden? Oder ist es das, was du tust?Antworten:
Ich habe dies an einigen Stellen getan. Das Ausführen mehrerer einfacher Abfragen und das Erstellen einer ID-Liste in der Anwendungslogik, selbst wenn die ID-Liste mehr als 10.000 IDs enthält, führte zu erheblichen Leistungssteigerungen. Der Tisch, den ich abfragte, hatte ungefähr 5 Millionen Datensätze und ein JOIN war schmerzhaft langsam. Nach dem Wechsel zur Verwendung von IN mit einer ID-Liste dauerte es ungefähr 1% der Zeit, die der JOIN benötigte.
quelle
Quatsch. Warum zusätzliche Anstrengungen unternehmen, wenn MySQL bereit ist, dies für Sie zu tun? Was die Leistung betrifft, gibt es wahrscheinlich keinen Unterschied, außer dass die aufgelösten Abfragen mehr Roundtrips zum Server erfordern.
OTOH, es gibt Fälle, in denen Sie den Optimierer überlisten können. Aber Ihr Beispiel war keines davon.
IN (Tausende von IDs) ist für den Server möglich, aber schmerzhaft. Es sortiert und de-dupt sie und belässt sie dann in einer Art Struktur für die wiederholte binäre Suche. Ich habe viele solcher Anfragen gesehen, aber nur die über 50.000 Artikel haben Augenbrauen hochgezogen.
Es gibt Zeiten, in denen dieses Umschreiben hilft:
->
Damit soll jedoch vermieden werden, dass zusätzlicher Müll herumgeschleppt wird, der vom LIMIT weggeworfen wird.
quelle
Ich habe dies in einigen Fällen getan, in denen es zu einer signifikanten, messbaren Geschwindigkeitssteigerung kam. Andererseits hat dies in anderen Fällen nicht viel geholfen. Ich glaube nicht, dass es eine universelle Antwort im Sinne von "Ja, das ist immer gut" oder "Nein, das ist immer schlecht" gibt. Ich gehe davon aus, dass "der Abfrageoptimierer normalerweise eine bessere Lösung findet als ein Programmierer": Bisher habe ich nur wenige Eckfälle gefunden, in denen ich die Arbeit des Abfrageoptimierers wie diesen ausführen musste.
Wie bei jeder Optimierung: Überprüfen Sie Ihre spezifischen Daten, profilieren Sie das Programm (nicht nur die Abfrage!) Und prüfen Sie, ob der Unterschied real ist oder nur Wunschdenken.
quelle