Frage

Ich refaktoriere einen Frühlings -JDBC -Code, in dem einige der teureren Fragen vorliegen "WÄHLEN AUS..." - und wollte gerade mit der Überprüfung beginnen, welche Spalten tatsächlich benötigt wurden und gerecht Wählen Sie x, y von .. Sie. Aber durch das lesen Ergebnis Die Klasse scheint, dass die meisten Daten faul geladen sind. Wenn du a machst Resultset.next () Es bewegt den Cursor in der Datenbank (Oracle 10G in dieser Anwendung) und wenn Sie a ResultSet.getXX () Es ruft diese Spalte ab. Mein Gedanke war also, dass wenn Sie eine tun "AUSWÄHLEN * " Aber nur die Spalten abrufen, die Sie möchten, die Sie nicht wirklich einen Performance -Hit machen. Denken Sie richtig darüber nach? Der einzige Ort, an den ich mir vorstellen kann, wo Sie dies weh tun Spalten, die die Abfrage treffen, dann wäre selbst dies nicht der Fall.

Gedanken?

Hinweis: Dies gilt nur für Standard Ergebnis, Ich weiss Cachedresultet wirkt anders.

War es hilfreich?

Lösung

Abhängig von der Tabellenstruktur, der Oracle -Version und der beteiligten Indizes ist es durchaus möglich, dass die Auswechslung der Spalten, die Sie auswählen, die Leistung erheblich verbessern würde, indem die Abfragepläne zum Besseren geändert werden. Bei den meisten Abfragen können die Leistungsvorteile durchaus minimal sein, aber insgesamt ist es im Allgemeinen eine gute Praxis, Spalten explizit zu benennen.

Der einfachste Fall, in dem die Leistung verbessert wird, wird auftreten, wenn Sie einen "abgedeckten Index" haben, den der Optimierer verwenden kann. Wenn alle Spalten, die Sie auswählen, und alle Spalten, nach denen Sie filtern, Teil eines einzelnen Index sind, ist dieser Index ein abgedeckter Index für die Abfrage. In diesem Fall kann Oracle vermeiden, jemals die Daten aus der Tabelle zu lesen und einfach den Index lesen.

Es gibt auch andere Fälle, in denen auch die Leistung verbessert wird. Der Optimierer kann möglicherweise durchführen Tabelle Eliminierung Wenn Sie Abfragen haben, gibt es Zwischenbekämpfung, die sich nicht auf die eventuelle Ausgabe auswirken. Wenn Sie alle Spalten auswählen, ist diese Optimierung nicht möglich. Wenn Sie Tabellen mit geketteten Zeilen haben, können Spalten auch die zusätzlichen Blöcke beseitigen, in denen sich die eliminierten Spalten befinden. Wenn in der Tabelle lange und LOB -Spalten vorhanden sind, würde auch die Auswahl dieser Spalten auch zu großen Verbesserungen führen.

Schließlich reduziert die Beseitigung von Spalten im Allgemeinen die Menge an Platz, die Oracle zum Sortieren und Hash -Ergebnissen benötigt, bevor sie sie über den Kabel versenden. Auch wenn das Ergebnis die Daten in den RAM des Anwendungsservers träge laden kann, kann es wahrscheinlich nicht in der Lage sein, Spalten über das Netzwerk faul zu holen. Wenn Sie alle Spalten aus der Tabelle auswählen, muss der JDBC-Treiber wahrscheinlich mindestens 1 vollständige Zeile gleichzeitig abrufen (wahrscheinlicher, dass er 10 oder 100 Zeilen pro Netzwerk-Roundtrip abreißt). Und da der Treiber nicht weiß, wann die Daten abgerufen werden, welche Spalten angefordert werden sollen, müssen Sie alle Daten über das Netzwerk versenden.

Andere Tipps

Ich wäre überrascht, wenn Sie von "Select *" zu "Select A, B, C" wechseln, gab Ihnen eine sinnvolle Leistungsverbesserung, es sei denn, Sie hatten eine große Anzahl von Spalten, die Sie nicht benötigten.

Dies ist alles sehr abhängig von Ihrer Datenbank, Ihrem Treiber und Ihrer Anwendung, und die meisten Verallgemeinerungen werden ziemlich bedeutungslos sein.

Die einzig zuverlässige Antwort, die Sie davon erhalten, besteht darin, das Benchmarking von "auszuwählen *", versuchen Sie "Select a, B, C" und prüfen Sie, ob sich eine Verbesserung wert ist, die es wert ist, verfolgt zu werden.

Ich weiß, dass in einer Anwendung, mit der ich beteiligt war auswählen * zu Wählen Sie x, y Hat uns einen kleinen Leistungsgewinn gekauft. Ich würde jedoch nachdrücklich empfehlen, ebenso wie Skaffman, dass Sie ein Profiling -Tool wie den integrierten Profiler von Oracle oder einen externen Profiler verwenden und große Datensätze durchführen, um Rauschen zu normalisieren (wie Netzwerkverkehr, Festplattenspin, Sonnenflecken , etc)

In den Umgebungen, in denen ich gearbeitet habe, wird in der Regel ausgewählt * einfach nie verwendet. Ich glaube, Skaffman & Aperkins haben wahrscheinlich Recht, dass der Leistungsgewinn klein ist. Dies ist eines dieser Dinge, in denen ich als Datenbankentwickler eine starke Meinung habe, dass Sie die Spalten, die Sie abrufen, immer benennen sollten, aber ich denke, es gibt möglicherweise keine wirkliche Grundlage dafür.

Hmmm ... Ich denke, aus Sicht der Wartbarkeit könnte man argumentieren, dass die Benennung der Spalten, die Sie abrufen, dazu dienen, Ihren Code ein wenig selbst zu dokumentieren. Select * gibt einem anderen Entwickler nicht so viele Informationen, um mit der Leitung zu arbeiten. Ob das und der kleine Leistungsnutzen das zusätzliche Tippen rechtfertigt Ich bin mir nicht sicher.

Ich bin bei @skaffman und anderen in diesem - bestenfalls kleinere Gewinne. Wenn Sie darüber nachdenken, wie Oracle Daten abruft und sich daran erinnert, dass es sich um Block -I/O handelt, wird die Datenbank unabhängig von den Spalten, nach denen Sie in Ihrem Client fragen, den gesamten Block abrufen, in dem der Datensatz sowieso gefunden wird. Wenn Ihr Kunde immer den gesamten Datensatz abruft (z. B. die Auswahl * in SQL * Plus), kann es zu einem Leistungsgewinn kommen, aber in Ihrer Situation, in der die Daten nur übertragen werden, wenn Sie danach fragen, dann wahrscheinlich nicht viel.

"Select *" kann für Apps, die zusammengestellt werden, böse sein. Wenn sich die Tabelle ändert, kann Ihr Code brechen. Deshalb würde ich es nicht benutzen.

Bearbeiten: Überall über alle hervorragenden Antworten hier nachdenken:

  1. Justin macht großartige Punkte zu bestimmten Situationen, in denen erhebliche Leistungsverbesserungen auftreten können.
  2. Codemonkey macht den guten Punkt über den Selbstdokumentationscode.
  3. Aperkins und Skaffman machen einen der besten Vorschläge von allen: Probieren Sie es aus, messen Sie und sehen Sie für Ihre eigene Situation, was die Auswirkungen haben.

+1 ist rundum ... Was ich nicht sehe, ist jemand, der über sich selbst fällt und "Select *" überhaupt empfiehlt. Wenn es einfach ist, die genauen Spalten anzugeben, die Sie benötigen, würde ich den Code dafür beheben.

Ich habe noch nie einen Leistungsgewinne zwischen dem und dem anderen beim Wechseln von Aussagen bemerkt - ich bin mir ziemlich sicher, dass Oracle sowieso zuerst den Inhalt einer ganzen Reihe packt, unabhängig von Wildcard- oder Säulenspezifikation. Es gibt viel größere Faktoren für die Leistung, die zuvor untersucht werden müssen (Indizes, Festplattengeschwindigkeit usw.).

Als Codierungspraxis würde ich vermeiden "SELECT *". Wenn Sie die spezifischen Spalten angeben Ich schreibe es.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top