Frage

ich auf einer datengesteuerten Web-Anwendung arbeite, die eine SQL 2005 (Standard Edition) Datenbank verwendet.

Eine der Tabellen ist ziemlich groß (8.000.000 + Reihen groß mit etwa 30 Spalten). Die Größe der Tabelle bewirkt offensichtlich die Leistung der Website, die Elemente aus der Tabelle über gespeicherte Prozeduren auswählt. Die Tabelle indiziert ist, aber immer noch die Leistung schlecht ist aufgrund der schieren Menge der Zeilen in der Tabelle - das ist ein Teil des Problems - wird die Tabelle als ebenso aktualisiert, lesen, damit wir können Indizes nicht hinzufügen / entfernen, ohne dass einer von die Operationen noch schlimmer.

Das Ziel, das ich hier habe, ist die Leistung zu erhöhen, wenn Elemente aus der Tabelle. Die Tabelle hat ‚aktuelle‘ Daten und alt / kaum berühren Daten. Die effektivste Lösung, die wir von zu diesem Zeitpunkt denken kann, ist die Tabelle in 2 zu trennen, das heißt, eine für alte Elemente (vor einem bestimmten Datum, sagen 1. Januar 2005) und eine für neuere Elemente (gleich oder vor 1. Januar 2005) .

Wir wissen von Dingen wie verteilten partitionierten Views - aber alle diese Funktionen erfordern Enterprise Edition, die der Kunde nicht kaufen (und nein, werfen Hardware es wird auch nicht passieren wird)

.
War es hilfreich?

Lösung

Sie können Ihren eigenen immer rollen „armer Mann Partitionierung / DPV,“ auch wenn es nicht wie die richtige Art und Weise riecht es zu tun. Dies ist nur ein breiter konzeptueller Ansatz:

  1. Erstellen Sie eine neue Tabelle für das laufende Jahr Daten - gleiche Struktur, gleiche Indizes. Stellen Sie die gespeicherte Prozedur, die auf die Haupt, großen Tisch schreibt in beiden Tabellen zu schreiben (nur vorübergehend). Ich empfehle, so dass die Logik in der gespeicherten Prozedur sagen IF CURRENT_TIMESTAMP> = ‚[some ganze Datum ohne Uhrzeit]‘ - das wird es, die machen einfach, die Daten in dieser Tabelle verfüllen die Änderung des Verfahrens vorgeDaten, die dort beginnt, anzumelden.

  2. eine neue Tabelle in der Geschichte für jedes Jahr erstellen, indem Sie SELECT INTO aus der Haupttabelle. Sie können in einer anderen Datenbank auf derselben Instanz tun dies den Aufwand in der aktuellen Datenbank zu vermeiden. Historische Daten werden sich nicht ändern Ich gehe davon aus, so in dieser anderen Datenbank könnte man sogar nur machen lesen, wenn es fertig ist (was dramatisch die Leseleistung verbessern).

  3. Wenn Sie eine Kopie der gesamten Tabelle haben, können Sie Ansichten erstellen, die nur das aktuelle Jahr eine andere Sicht verweisen, die mit 2005 auf das laufende Jahr verweist (von UNION ALL zwischen der aktuellen Tabelle verwenden und die in den anderen Datenbank, die> = 2005), und eine andere, die alle drei Sätze von Tabellen verweist (die erwähnten, und die Tabellen, die vor dem Datum 2005). Natürlich kann man dies noch brechen, aber ich wollte nur minimal um das Konzept zu halten.

  4. Ändern Sie Ihre gespeicherten Prozeduren, die die Daten lesen „intelligenter“ zu sein - wenn der Zeitraum fällt angefordert Jahr im aktuellen Kalender, die kleinste Ansicht verwenden, die nur lokal ist; wenn der Datumsbereich ist> = 2005 dann die zweite Ansicht verwenden, sonst die dritte Ansicht verwenden. Sie können mit gespeicherten Prozeduren ähnliche Logik folgen, die schreiben, wenn Sie mehr tun, als nur neue Daten einzufügen, die nur für das laufende Jahr relevant sind.

  5. An diesem Punkt sollten Sie in den massiven Tabelle einfügen können, stoppen, und sobald alles bewiesen ist, zu funktionieren, legen Sie es und etwas Speicherplatz zurück (und damit meine ich Platz in der Datendatei bedeuten Freisetzung (en) für die Wiederverwendung, keine Schrumpf db Durchführung -., da Sie diesen Raum nutzen werden wieder)

Ich habe nicht alle Details Ihrer Situation aber bitte folgen, wenn Sie Fragen oder Bedenken haben. Ich habe diesen Ansatz in mehreren Migrationsprojekten einschließlich eines verwendet, die auf der rechten Seite jetzt geht.

Andere Tipps

  

Leistung aufgrund der schieren Menge der Zeilen in der Tabelle schlecht ist

8 Millionen Zeilen klingt nicht alles verrückt. Haben Sie Ihre Abfragepläne überprüfen?

  

wird die Tabelle als ebenso gelesen wie aktualisiert

aktualisieren Sie tatsächlich eine indexierte Spalte oder ist es gleich lesen und eingefügt

  

(und nein, wirft Hardware es wird nicht passieren, entweder)

Das ist schade, weil RAM spottbillig ist.

Rebuild alle Indizes. Dies wird steigern Leistung von Abfragen. Wie es funktioniert diese und mehr auf Effekt auf neu erstellen von gruppierten und nicht -clustered Index hier

Zum anderen führen de-Fragmentierung auf dem Laufwerk, auf dem der DB gespeichert wird.

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