Wenn db_select viel langsamer ist als db_query, warum sollte ich es verwenden?

69

Hintergrundinformationen hierzu finden Sie unter http://drupal.org/node/1067802 .

In welchen Situationen möchte ich db_select () verwenden oder sollte ich mich nur auf db_query verlassen?

Chris Cohen
quelle

Antworten:

88

Es gibt 5 Gründe, SelectQuery zu verwenden

  • Sie erstellen dynamische Abfragen mit einer unterschiedlichen Anzahl von Bedingungen, Verknüpfungen, Feldern usw. Ein Beispiel finden Sie unter field_read_fields () .

  • Sie möchten sogenannte Extender verwenden . Beispiele für Extender sind PagerDefault (ersetzt pager_query () ) und TableSort (ersetzt tablesort_sql () ). Diese ermöglichen es, SelectQuery um zusätzliche Funktionen zu erweitern. Siehe auch Wie erstelle ich mit einem Pager sortierbare Tabellen mit Daten aus einer benutzerdefinierten Tabelle? . Ein Beispiel: node_page_default () .

  • Sie möchten zulassen, dass andere Module Ihre Abfragen ändern. Dann können Sie sogenannte Tags hinzufügen, und SelectQuery ruft automatisch einen entsprechenden Alter Hook für dieses Tag auf. Ich verlasse mich bei meinem Privatemsg-Modul stark darauf (das haben wir bereits in D6 mit einem benutzerdefinierten Query Builder gemacht).

  • Wenn Sie das node_access-System verwenden möchten / müssen, um nur Knoten anzuzeigen, die der Benutzer sehen darf. Fügen Sie einfach das Tag 'node_access' zu Ihrer $ query hinzu. Dies ersetzt db_rewrite_sql ().

  • SelectQuery verfügt über einige Funktionen, mit denen der Code in allen unterstützten Datenbanken gleich funktioniert. Zum Beispiel gibt es SelectQuery :: orderRandom () . Und wenn Sie eine LIKE-Bedingung haben, stellt -> condition ('field', $ value, 'LIKE') sicher, dass bei diesem Vergleich immer die Groß- und Kleinschreibung nicht beachtet wird. In D6 mussten Sie LOWER () für das verwenden, was viel langsamer war. Aber AFAIK, es gibt momentan nicht mehr als diese beiden.

Wenn keiner dieser Gründe für einen bestimmten Fall zutrifft, verwenden Sie db_query ().

Berdir
quelle
1
Es wurde ein fünfter Punkt hinzugefügt: Datenbankportabilitätsfunktionen wie orderRandom () und case insensitive LIKE.
Berdir
6
Als sechsten Grund möchte ich die datenbankübergreifende Kompatibilität hinzufügen. Oracle-Abfragen haben beispielsweise eine Syntax, die sich in einigen Punkten von MySQL, Postgres usw. unterscheidet. Es ist viel einfacher, Code zu schreiben, um die richtige Syntax aus einem db_select () zu generieren, als wenn es sich um einen nicht sehr Oracle-kompatiblen Abfragecode handelt wird direkt in db_query () gespeichert.
BrianV
9

Die Dokumentation überdb_query() sagt:

Verwenden Sie diese Funktion für SELECT-Abfragen, wenn es sich nur um eine einfache Abfragezeichenfolge handelt. Wenn der Aufrufer oder andere Module die Abfrage ändern müssen, verwenden Sie stattdessen db_select ().

marcvangend
quelle
Danke, aber das ist ziemlich unspezifisch. Die Definition des Begriffs "einfache Abfragezeichenfolge" kann daher durchaus interpretiert werden. Wenn ich 4 Tabellen mit 6 Joins auswähle, ist das immer noch eine einfache Abfrage, oder sollte sie stattdessen mit db_select () durchgeführt werden?
Chris Cohen
3
Es geht nicht um „einfache Abfrage“ , sondern um eine „einfache Abfrage - String “ und einfach bedeutet eigentlich fest codierten und nicht dynamisch. Siehe meine Antwort für weitere Details :)
Berdir
9

Ich verwende immer db_select, da ich Lesbarkeit, Wartbarkeit und datenbankübergreifende Kompatibilität gegenüber kleinen Leistungssteigerungen bevorzuge. Darüber hinaus geben die in der genannten Ausgabe angegebenen Zahlen meines Erachtens ein falsches Bild der Gesamtleistung. Wir sprechen von einem Unterschied von 300 Mikrosekunden bei einer Abfrage, die bei der Rückgabe von mehr als einer einzelnen Spalte häufig im Bereich von mehreren Millisekunden ausgeführt wird. Und ich würde mich nicht wundern, wenn es nur einen einzigen Aufwand (Laden von Klassen) gibt und daher die Unterschiede für eine vollständige (Seiten-) Anfrage weitaus geringer sind.

fietserwin
quelle
Der Leistungsunterschied ist nicht so einfach; Siehe Vergleich der Leistung von db_query und db_select . Im Allgemeinen empfehle ich db_query anstelle von db_select, es sei denn, Sie benötigen eine der in Berdir's Antwort genannten Besonderheiten.
Geerlingguy