TABLESAMPLE возвращает неправильное количество строк?

Я только что обнаружил предложениеTABLESAMPLE , но, к удивлению, оно не возвращает число. строк, которые я указал.

В таблице, которую я использовал, примерно 14 миллионов строк, и мне нужна была произвольная выборка из 10 000 строк.

select * from tabData TABLESAMPLE(10000 ROWS)

При каждом выполнении я получаю не 10000, а другое число (между 8000 и 14000).

Что здесь происходит, я неправильно понял предназначение TABLESAMPLE?

Редактировать:

Ссылка Давидадовольно хорошо объясняет это.

Это всегда возвращает 10000 примерно случайных строк эффективным способом:

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

и опция REPEATABLEпомогает всегда получать одно и то же (если только данные не изменились)

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

Поскольку я хотел знать, дороже использовать TABLESAMPLEс большим количеством строк, чтобы гарантировать (?), что я получаю правильный номер строки, я измерил его;

1.loop (20 раз):

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.loop (20 раз):

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: встречная проверка со 100% случайными строками с использованием ORDER BY NEWID():

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

(10000 row(s) affected)

Отменено после одного выполнения, которое длилась 23 минуты

Заключение:

Таким образом, подход с точным TOPпредложением и большим числом в TABLESAMPLEнемедленнее. Следовательно, это очень эффективная альтернатива ORDER BY NEWID(), если не имеет значения, что строки являются случайными не для каждой строки, а для каждого уровня страницы (каждой странице 8K для таблицы присваивается случайное значение).

10
задан Tim Schmelter 17 March 2014 в 14:39
поделиться