TABLESAMPLE zwraca błędną liczbę wierszy?

Właśnie odkryłemTABLESAMPLE klauzula, ale zaskakująco nie zwraca liczby określonych wierszy.

Tabela, której użyłem, ma ~ 14M wierszy i potrzebowałem dowolnej próbki 10000 wierszy.

select * from tabData TABLESAMPLE(10000 ROWS)

Dostaję nie 10000, ale inny numer za każdym razem, gdy go wykonam (między 8000 a 14000).

Co tu się dzieje, czy źle zrozumiałem zamierzony celTABLESAMPLE?

Edytować:

Link Davida wyjaśnia to całkiem dobrze.

Zwraca to zawsze 10000 mniej więcej losowych wierszy w skuteczny sposób:

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

iREPEATABLE opcja pomaga uzyskać zawsze to samo (chyba że dane uległy zmianie)

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

Ponieważ chciałem wiedzieć, czy korzystanie z niego jest droższeTABLESAMPLE z dużą liczbą wierszy, aby zapewnić (?), że otrzymam prawidłową liczbę wierszy, zmierzyłem ją;

1. pętla (20 razy):

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. pętla (20 razy):

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: sprawdź 100% losowych wierszy przy użyciu ORDER BY NEWID ():

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

(10000 row(s) affected)

Anulowane po jednym wykonaniu, które trwało23 minuty

Wniosek:

Zaskakująco podejście z dokładnymTOP klauzula i duża liczba wTABLESAMPLE jestnie wolniej. Dlatego jest to bardzo skuteczna alternatywa dlaORDER BY NEWID() jeśli nie ma znaczenia, że ​​wiersze nie są losowe w każdym wierszu, ale na poziomie strony (każda strona 8K tabeli ma wartość losową).

questionAnswers(4)

yourAnswerToTheQuestion