Frage

Ich benutze SQL Server und habe das Konzept der Schlüsselsuche genau untersucht.

http://blog.sqlauthority.com/2009/10/07/sql-server-query-optimization-remove-bookmarkmark-lookup-remove-rid-lookup-remove-key-lookup/

Wenn Sie also über eine Schlüssel suchen, können Sie einen Index mit den Spalten 'Include' erstellen, um die Nicht -Index -Spalten abzudecken, die Sie in der Auswahlanweisung haben.

Zum Beispiel,

SELECT ID, FirstName FROM OneIndex WHERE City = 'Las Vegas'
GO

Dieser Index enthält eine wichtige Suche.

CREATE NONCLUSTERED INDEX [IX_OneIndex_City] ON [dbo].[OneIndex]
(
[City] ASC
) ON [PRIMARY]
GO

Aber dieser wird die wichtige Suche entfernen.

CREATE NONCLUSTERED INDEX [IX_OneIndex_Include] ON [dbo].[OneIndex]
(
City
) INCLUDE (FirstName,ID) ON [PRIMARY]
GO

Ich meine, wie viel Einfluss auf die Leistung hat? Die wichtigste Suche hat einen Bedienerkosten von 0,295969 (99%), aber was bedeutet das wirklich?

Woher wissen Sie, dass Sie dort den zweiten Index benötigen, und an welchen Punkt wird es in der Fall, dass Sie versuchen, zu viele Indizes hinzuzufügen, und es lohnt sich nicht?

Es scheint mir, dass einige Abfragen Index -Scans, wichtige Lookups enthalten und immer noch sehr schnell zu funktionieren scheinen.

War es hilfreich?

Lösung

Stellen Sie sich vor, die Telefongesellschaft hat eine Liste von Telefonnummern, einschließlich wer der Kunde ist, wo sie wohnen, wie ihre Abrechnungsnummer und so weiter ist. Der Hauptschlüssel könnte die Telefonnummer sein.

Sie geben dir die weißen Seiten. Das ist wie ein nicht klusterer Index, der mit Namen geordnet ist, einschließlich Spalten wie der Adresse.

Wenn Sie alle Farleys im Buch finden möchten und an ihren Adressen interessiert sind, dann sind die weißen Seiten alles, was Sie brauchen. Sie können schnell zu den Farleys suchen (das FS und so weiter finden), und dann haben Sie alle Informationen, die Sie benötigen.

Aber wenn Sie ihre Abrechnungsnummern möchten, müssen Sie eine Suche durchführen. Sie können schnell alle Telefonnummern der Farleys finden, aber dann müssen Sie jeden von ihnen (Hunderte) einnehmen und im Hauptindex (Clustered) eine weitere Suche (Such) durchführen, die von der Telefonnummer bestellt wird. Jedes davon sind ungefähr die gleichen Kosten wie die Suche nach den Farleys, wodurch Ihre Abfragestellungen verschlechtert werden.

Und es gibt eine Schwelle. Irgendwann wird die Datenbank erkennen, dass es schneller ist, jede Seite des Clustered -Index durchzugehen und jeden Datensatz zu überprüfen, um festzustellen, ob sie von Interesse ist.

Ernsthaft - suchende Lookups loswerden. Ihre Abfragen mögen jetzt schnell sein, werden aber wahrscheinlich nicht skalieren.

Andere Tipps

Hintergrund

In dem schlimmsten Fall, Eine Abfrage, die eine Suche enthält, muss für Zeilen zum physischen Speicher gehen, für die Spaltendaten erforderlich sind, die nicht vom nicht klusterten Index abgedeckt werden. In dem Sehr schlimmste In schlimmsten Fällen erfordert jede Suche ein separates E/A, und die Ausführung muss darauf warten, dass die Daten dieser einzelnen Zeile vor dem Fortfahren zurückkommen. Dieses Szenario hat normalerweise schwerwiegende Auswirkungen auf die Leistung, wenn die Suche a verarbeiten muss von Bedeutung Reihenanzahl.

Deshalb bekommen Lookups eine so schlechte Presse. Beachten Sie andererseits, dass die Fähigkeit zur Ausführung in SQL Server 2000 eingeführt wurde alle die Informationen, die zur Befriedigung der Abfrage erforderlich sind; In allen anderen Fällen musste es über einen Cluster -Index auf Daten zugreifen (falls vorhanden oder ein Heap -Scan ansonsten). Wenn die Lookups immer so sehr schlecht wären, hätte SQL Server sie sicherlich nie vorgestellt.

In SQL Server 2000+, wo wir einen nicht klusterten Index haben, der nützliche Bestellung und/oder (die meisten) die von einer Abfrage erforderlichen Spalten liefert, und wo die Anzahl der Suchvorgänge wahrscheinlich relativ klein ist, unter Verwendung des nicht klusterten Index und der Ausführung a begrenzte Anzahl Die Nachschläge auf der Basistabelle sind wahrscheinlich die billigste verfügbare Zugangsmethode (obwohl ein vollständig bedeckender nicht klusterer Index natürlich noch billiger ist).

In vielen Fällen ist es nur nicht praktisch Erstellen Sie so viele nicht klusterische Indizes wie erforderlich, um das Scannen der Basistabelle für alle gängigen Abfragen zu vermeiden. Ein Grund könnte sein INSERT/UPDATE/DELETE/MERGE Die Leistung ist wichtiger als die Abfragegeschwindigkeit (denken Sie daran, dass Datenänderungsvorgänge auch alle betroffenen nicht klusterten Indizes beibehalten müssen). Ein weiterer Grund könnte Raum sein; Jeder nicht klusterte Index repräsentiert eine Kopie einer Teilmenge der Spalten der Basistabelle (oder darauf, Ausdrücke), die gerade unterschiedlich sortiert sind. Weitere Kopien der Daten bedeuten mehr Speicherplatz und mehr Dinge, die im In-Memory-Datencache von SQL Server um Platz konkurrieren.

In anderen Fällen können wir nur ein paar zusätzliche Indizes (möglicherweise in SQL Server 2008+ gefiltert) mit gerade genug erstellen INCLUDE Spalten, um die überwiegende Mehrheit der leistungskritischen Abfragen zu erfüllen, ohne die Leistung der Datenänderung zu stark zu beeinträchtigen und ohne zu viel zusätzlichen Speicherplatz zu viel zu verwenden. Das Ausgleich der konkurrierenden Überlegungen macht das Index -Tuning mehr Kunst als Wissenschaft.

Kosten

Sie fragen sich, was die 99% für den Suchbetreiber tatsächlich kosten meint im Abfrageplan. Die Kostenkomponente des Abfrageoptimierers erzeugt eine geschätzt Kosten für diesen Vorgang, der 99% der Gesamtsumme beträgt geschätzt für die Abfrage. Die Zahl selbst (0,29) bedeutet überhaupt nicht viel; Für alle praktischen Zwecke sollten Sie es als eine interne Anzahl ohne Einheit betrachten, die vom Optimierer beim Vergleich alternativer Strategien für diese bestimmte Abfrage intern verwendet wird.

Die geschätzten Kosten berücksichtigen keine Berücksichtigung Ihrer Hardware, Konfiguration, Anwendungsanforderungen oder sehr viel anderes. Das vom Optimierer verwendete Kostenmodell enthält eine erhebliche Anzahl von Heuristiken und die Vereinfachung der Annahmen, die passieren Die meiste Zeit für die meisten Abfragen an den meisten Hardware angemessene Pläne zu erstellen. Das heißt nicht, dass es gibt nein Korrelation zwischen kostengünstigen Betreibern in Plänen und Leistung; Vielmehr ist die Verbindung oft viel schwächer als allgemein erwartet. Überprüfen Sie auf jeden Fall zuerst die Gründe für hoch geschätzte kostengünstige Planplaner, sondern behandeln Sie die Informationen jedoch nicht als etwas anderes als eine möglicherweise möglicherweise fehlerhafte Schätzung.

Einfluss

Ich möchte auch einige Faktoren erwähnen, die die Auswirkungen von Lookups verbessern können. Zuerst erwähnte ich zu Beginn, dass der schlimmste Fall mit Reihen-für-Reihen-physische i/o. Dies wird offensichtlich vermieden, wenn die Datenseiten (Clustered -Index oder Heap) zur Befriedigung der SOKUPS bereits im Speicher sind (Datencache). Wenn dies der Fall ist, kann der Ausführungszeitunterschied zwischen einem Plan mit einem Nachschlag und einem Abdeckindex unermesslich sein. Selbst wenn physische E/A erforderlich ist, ist es Ihnen möglicherweise egal, wenn die Anzahl der Lesevorgänge klein ist. (Wie wahrscheinlich ist, dass Datenseiten für eine Tabelle im Datencache enthalten sind, hängt von vielen Faktoren ab und ist spezifisch für Ihre Hardware und Umstände.)

Wo mehr als ein wenig physischer E/A benötigt wird, können die Auswirkungen der Suchuntersuchungen immer noch durch Optimierungen im Abfrageplan reduziert werden. Wenn SQL Server erwartet, dass die Anzahl der Nachschläge von Bedeutung ist, kann es sich möglicherweise um explizit sortieren, wenn die Zeilen, die in die verschachtelten Loops eintreten, in der Reihenfolge der nicht klusterten Schlüsseln an der Suche nach dem Suchanlagen ausdrücklich sortiert werden. Diese Neuordnung fördert das sequentielle Lesen des nicht klusterten Index, der möglicherweise sehr schneller ist als zufällige I/A auf Ihrer Hardware.

Mit oder ohne explizit WithOrderedPrefetch oder WithUnorderedPrefetch Attribute vorhanden. In beiden Fällen schaut die Abfrage -Ausführungsmaschine im Indexschlüsselstream aus, die die Lookups und Probleme vorantreiben lesen Sie weiter liest. Die Idee ist, herauszufinden asynchron Lesen Sie Anfragen an das I/A -System für Datenseiten, die in Kürze benötigt werden, damit die Suchseite eine Datenseite benötigt, die bereits im Speicher vorhanden ist.

Unter idealen Bedingungen (geringe Fragmentierung, guter Abfrageplan, Hochleistungs-E/A-System) kann der Mechanismus von Read-Ahead durchaus schnell genug sein, um zu verhindern, dass selbst große parallele Abfragepläne jemals darauf warten, dass die E/A abgeschlossen ist. Dies gilt insbesondere in der Enterprise Edition, die sehr große einzelne E/A -Anfragen ausstellen kann (bis zu 2 MB pro Anforderung, wenn der Speicher dient). Andererseits kann Ihre Abfrage unter weniger als idealer (normaler!) Bedingungen schrecklich leiden, da sie auf langen I/A -Warteschlangen wartet oder das I/A -System nicht hart genug fährt. Die schlimmste Fallleistung von Schlüsselsuche kann in der Tat sehr schlecht sein.

Zusammenfassung

Zusammenfassend lässt sich sagen allgemein Ich möchte Suchuntersuchungen vermeiden Wo es sinnvoll ist, dies zu tun. Bei kleinen Abfragen (die klein bleiben) können Sie entscheiden, dass der Overhead von zusätzlichen Indizes (Raum und Wartung) nicht gerechtfertigt ist, angesichts der umfassenderen Bedürfnisse des Systems und seiner Benutzer.

Letztendlich ist dies alles Teil der Kunst und Wissenschaft, die Datenbankentwicklung und -verwaltung ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top