2015-05-26 8 views
8

Ich möchte eine zufällige Zeile aus einer sehr großen Tabelle (10 mil Datensätze) auswählen. Daher scheint die am häufigsten anzutreffende Strategie wie RAND() und NEWID() nicht praktikabel zu sein.SQL Large Table wählen zufällige Zeilenstrategie

Ich habe die folgende Strategie ausprobiert und würde gerne wissen, ob dies der idealste Weg ist.

  1. Erstellen Sie ein neues Feld namens ‚RandomSort‘ als UniqueIdentified

  2. Am Ende jeder Stunde/Tag wird ein Update RandomSort = NewID() auf die gesamte Tabelle tun

  3. Jedes Mal, wenn ich fragen müssen, ich tun kann, ein Top 10 Order by RandomSort

Es ist die Arbeit erledigt bekommt (besser als ORDER BY NewID), aber nicht sicher, ob dies die beste Praxis so weit ist?

+0

Hat die Tabelle einen ganzzahligen Primärschlüssel? –

+0

Warum sagen Sie, dass 'RAND()' und 'NEWID()' unpraktisch ist? –

+3

Es scheint gut zu sein. Aber betont das UPDATE nicht zu sehr die DB? – Galma88

Antwort

3

Fügen Sie eine Identitätsspalte "rowid" (int oder bigint abhängig von Ihrer Tabellengröße) hinzu und erstellen Sie einen eindeutigen nicht gruppierten Index.

Die folgende Abfrage verwendet die NEWID() Funktion etwa ein Prozent der Zeilen der Tabelle zurückzukehren:

SELECT * FROM MyTable 
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), rowID) & 0x7fffffff AS float)/CAST (0x7fffffff AS int) 

Die rowid Spalte in dem CHECKSUM Ausdruck enthalten ist, so dass NEWID() auswertet einmal pro Zeile zu erreichen, Probenahme pro Reihe. Der Ausdruck CAST(CHECKSUM(NEWID(), rowid) & 0x7fffffff AS float/CAST(0x7fffffff AS int) wertet einen zufälligen Gleitkommawert zwischen 0 und 1 aus.

In der Tat könnten Sie jede spaltenindizierte Spalte in Ihrer Tabelle verwenden (glaube ich).

Wenn Sie wollen einfach nur eine einzige zufällige Reihe wählen:

SELECT TOP 1 * FROM table 
WHERE rowid >= RAND(CHECKSUM(NEWID())) * (SELECT MAX(rowid) FROM table) 

Diese in konstanter Zeit arbeitet, sofern die rowid Spalte indiziert ist. Hinweis: Dies setzt voraus, dass rowid gleichmäßig im Bereich 0..MAX(rowid) verteilt ist, daher die vorgeschlagene Identitätsspaltenaddition. Wenn Ihr Dataset eine andere Verteilung aufweist, sind die Ergebnisse verzerrt (d. H. Einige Zeilen werden häufiger als andere ausgewählt).

+0

Wird dies versuchen. Vielen Dank. Frage: Die Methode, die ich oben erwähnte, wird einen vollständigen Tabellenscan richtig machen? Während Ihre Methode nicht? – Lasker

+1

Ja, das ist richtig. –