Ich frage, weil sich so viele der Fragen, die ich in SQL sehe, auf Folgendes belaufen: "Das ist langsam. Wie beschleunige ich das?" Oder in Tutorials heißt es: "Mach das so und nicht so, weil es schneller ist".
Mir scheint, ein großer Teil von SQL weiß, wie ein Ausdruck ausgeführt wird, und wählt aus diesem Wissen die Ausdrucksstile, die eine bessere Leistung erbringen. Dies steht nicht im Einklang mit einem Aspekt der deklarativen Programmierung - dem Verlassen des Systems, um zu entscheiden, wie die Berechnung am besten durchgeführt werden soll, wobei Sie lediglich angeben, was die Berechnung ergeben soll.
Sollte sich eine SQL-Engine nicht darum kümmern, ob Sie sie verwendet haben in
, exists
oder join
ob sie wirklich deklarativ ist, sollte sie Ihnen nicht einfach die richtige Antwort in angemessener Zeit geben, wenn dies mit einer der drei Methoden möglich ist? Dieses letzte Beispiel wird durch diesen kürzlich veröffentlichten Beitrag veranlasst, der von dem Typ ist, der in meinem einleitenden Absatz erwähnt wurde.
Indizes
Ich denke, das einfachste Beispiel, das ich hätte verwenden können, bezieht sich auf das Erstellen eines Index für eine Tabelle. Das Gumph hier auf w3schools.com versucht sogar, es als etwas zu erklären, das der Benutzer aus Leistungsgründen nicht sieht. Ihre Beschreibung scheint SQL-Indizes in das nicht deklarative Lager zu stellen, und sie werden aus reinen Leistungsgründen routinemäßig von Hand hinzugefügt.
Ist es der Fall, dass es irgendwo eine ideale SQL-Datenbank gibt, die aussagekräftiger ist als alle anderen, aber weil es so gut ist, hört man nicht davon?
quelle
select whatever from sometable where FKValue in (select FKValue from sometable_2 where other_value = :param)
. Es sollte trivial sein zu sehen, wie man das mit aexists
oder a wiedergibtjoin
.Antworten:
SQL ist theoretisch deklarativ. Aber Sie wissen, was sie über den Unterschied zwischen Theorie und Praxis sagen ...
Im Kern war das Konzept der "deklarativen Programmierung" nie wirklich effektiv und wird es wahrscheinlich auch nie tun, bis wir einen AI-basierten Compiler haben, der in der Lage ist, Code zu betrachten und die Frage "Was ist die Absicht dieses Codes?" Zu beantworten. intelligent, auf die gleiche Weise wie die Person, die es geschrieben hat. Das Herzstück jeder deklarativen Sprache ist eine ganze Reihe von imperativem Code, der verzweifelt versucht, dieses Problem ohne die Hilfe einer KI zu lösen.
Oft funktioniert es überraschend gut, da es sich bei den häufigsten Fällen um häufige Fälle handelt , von denen die Leute, die die Implementierung der Sprache geschrieben haben, wussten und gute Möglichkeiten fanden, damit umzugehen. Aber dann stoßen Sie auf einen Randfall, den der Implementierer nicht berücksichtigt hat, und Sie sehen, dass sich die Leistung schnell verschlechtert, da der Interpreter gezwungen ist, den Code viel wörtlicher zu nehmen und weniger effizient damit umzugehen.
quelle
I rarely hit an edge case in any of them that couldn't be solved within the framework.
Ja, das ist der springende Punkt: Sie müssen einen Weg finden, um sie innerhalb des Frameworks zu lösen, da das Framework nicht intelligent genug ist, um es für Sie so zu lösen, wie Sie es ursprünglich deklariert haben.Ich habe vor einigen Tagen nach einer SQL-Optimierung darüber nachgedacht. Ich denke, wir können uns darauf einigen, dass SQL eine "deklarative Sprache" in der Definition von Wikipedia ist:
Wenn Sie sich vorstellen, wie viele Dinge hinter den Kulissen erledigt werden (Betrachten von Statistiken, Entscheiden, ob ein Index nützlich ist, Suchen nach einem verschachtelten, zusammengeführten oder Hash-Join usw.), müssen Sie zugeben, dass wir nur ein hohes Niveau angeben Logik, und die Datenbank kümmerte sich um alle Low-Level-Kontrollflusslogik.
Auch in diesem Szenario benötigt der Datenbankoptimierer manchmal einige "Hinweise" vom Benutzer, um die besten Ergebnisse zu erzielen.
Eine andere gebräuchliche Definition von "deklarativer" Sprache ist (ich kann keine autorisierende Quelle finden):
Wenn wir diese Definition akzeptieren, stoßen wir auf die vom OP beschriebenen Probleme.
Das erste Problem ist, dass SQL uns mehrere gleichwertige Möglichkeiten bietet, "dasselbe Ergebnis" zu definieren. Wahrscheinlich ist das ein notwendiges Übel: Je mehr Ausdruckskraft wir einer Sprache verleihen, desto wahrscheinlicher ist es, dass es verschiedene Möglichkeiten gibt, dasselbe auszudrücken.
Als Beispiel wurde ich einmal gebeten, diese Abfrage zu optimieren:
Da die Typen viel kleiner waren als die des Kunden und ein Index auf dem
cust_type
Kundentisch vorhanden war, habe ich eine große Verbesserung erzielt, indem ich ihn folgendermaßen umgeschrieben habe:In diesem speziellen Fall, als ich den Entwickler fragte, was er erreichen wolle, sagte er mir: "Ich wollte alle Kundentypen, für die ich mindestens einen Kunden hatte", das ist übrigens genau die Beschreibung der Optimierungsabfrage.
Wenn ich also eine gleichwertige und effizientere Abfrage finden könnte, warum kann das Optimierungsprogramm nicht dasselbe tun?
Ich vermute, dass es zwei Hauptgründe gibt:
SQL drückt Logik aus:
Da SQL eine übergeordnete Logik ausdrückt, möchten wir wirklich, dass der Optimierer uns und unsere Logik überlistet? Ich würde begeistert "Ja" rufen, wenn ich nicht immer den Optimierer zwingen müsste, den effizientesten Ausführungspfad auszuwählen. Ich denke, die Idee könnte sein, dem Optimierer zu erlauben, sein Bestes zu geben (und auch unsere Logik zu überarbeiten), uns aber einen "Hinweismechanismus" zu geben, um zu retten, wenn etwas verrückt wird (es wäre, als hätte man das Rad + Bremsen ein autonomes Auto).
Mehr Auswahl = mehr Zeit
Selbst der beste RDBMS-Optimierer testet nicht ALLE möglichen Ausführungspfade, da sie sehr schnell sein müssen: Wie gut wäre es, eine Abfrage von 100 ms auf 10 ms zu optimieren, wenn ich jedes Mal 100 ms für die Auswahl des besten Pfads aufwenden müsste? Und das mit dem Optimierer, der unsere "High-Level-Logik" respektiert. Wenn auch alle entsprechenden SQL-Abfragen getestet werden sollen, kann die Optimierungszeit um ein Vielfaches anwachsen.
Ein weiteres gutes Beispiel für das Umschreiben von Abfragen, zu dem kein RDBMS in der Lage ist, ist (aus diesem interessanten Blog-Beitrag ).
als kann so geschrieben werden (analytische Funktionen erforderlich)
quelle