TABLESAMPLE liefert falsche Zeilenanzahl?

Ich habe gerade das entdecktTABLESAMPLE Klausel, aber überraschenderweise gibt es nicht die Anzahl der Zeilen zurück, die ich angegeben habe.

Die Tabelle, die ich verwendet habe, hat ~ 14M Zeilen und ich wollte eine beliebige Stichprobe von 10000 Zeilen.

select * from tabData TABLESAMPLE(10000 ROWS)

Ich erhalte nicht 10000, sondern jedes Mal eine andere Nummer (zwischen 8000 und 14000).

Was hier los ist, habe ich den beabsichtigten Zweck von missverstandenTABLESAMPLE?

Bearbeiten:

Davids Verbindung erklärt es ziemlich gut.

Dies gibt auf effiziente Weise immer 10000 ungefähr zufällige Zeilen zurück:

select TOP 10000 * from tabData TABLESAMPLE(20000 ROWS);

und dasREPEATABLE Option hilft immer das Gleiche zu bekommen (sofern sich die Daten nicht geändert haben)

select TOP 10000 * from tabData TABLESAMPLE(10000 ROWS) REPEATABLE(100);

Da wollte ich wissen, ob es teurer ist, es zu benutzenTABLESAMPLE mit einer großen Anzahl von Zeilen, um sicherzustellen (?), dass ich die richtige Zeilennummer erhalte, habe ich es gemessen;

1. Schleife (20 Mal):

select TOP 10000 * from tabData TABLESAMPLE(10000 ROWS);

(9938 row(s) affected)
(10000 row(s) affected)
(9383 row(s) affected)
(9526 row(s) affected)
(10000 row(s) affected)
(9545 row(s) affected)
(9560 row(s) affected)
(9673 row(s) affected)
(9608 row(s) affected)
(9476 row(s) affected)
(9766 row(s) affected)
(10000 row(s) affected)
(9500 row(s) affected)
(9941 row(s) affected)
(9769 row(s) affected)
(9547 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(9478 row(s) affected)
First batch(only 10000 rows) completed in: 14 seconds!

2. Schleife (20 Mal):

select TOP 10000 * from tabData TABLESAMPLE(10000000 ROWS);

(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
Second batch(max rows) completed in: 13 seconds!

3.loop: counterscheck mit 100% zufälligen Zeilen mit ORDER BY NEWID ():

select TOP 10000 * from tabData ORDER BY NEWID();

(10000 row(s) affected)

Abgebrochen nach einer Ausführung, die dauerte23 Minuten

Fazit:

So überraschend ist der Ansatz mit einem exaktenTOP Klausel und eine große Anzahl inTABLESAMPLE istnicht Langsamer. Daher ist es eine sehr effiziente Alternative zuORDER BY NEWID() Wenn es nicht wichtig ist, dass die Zeilen nicht zufällig pro Zeile, sondern pro Seitenebene sind (Jede 8-KB-Seite für die Tabelle erhält einen zufälligen Wert).

Antworten auf die Frage(4)

Ihre Antwort auf die Frage