Вопрос по sql-server – TABLESAMPLE возвращает неправильное количество строк?

10

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

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

select * from tabData TABLESAMPLE(10000 ROWS)

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

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

Edit:

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

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

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

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

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

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

1. цикл (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. цикл (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 minutes

Conclusion:

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

Ваш Ответ

4   ответа
4

Увидетьстатья здесь, Вам нужно добавить верхнее предложение и / или использовать параметр repeatable, чтобы получить желаемое количество строк.

Error: User Rate Limit ExceededTOPError: User Rate Limit Exceeded Rango
Error: User Rate Limit ExceededtopError: User Rate Limit Exceededtablesample (10 percent).
Error: User Rate Limit Exceededselect TOP 10000 * from tabData TABLESAMPLE(20000 ROWS);Error: User Rate Limit Exceeded Rango
Error: User Rate Limit ExceededlessError: User Rate Limit Exceeded
Error: User Rate Limit ExceededxError: User Rate Limit ExceededTABLESCAMPLE(x ROWS)Error: User Rate Limit ExceedednError: User Rate Limit ExceededTOP(n)Error: User Rate Limit ExceedednError: User Rate Limit ExceededTABLESAMPLE(x ROWS)Error: User Rate Limit Exceeded
1

Я наблюдал то же самое.

Объяснение страницы определенно имеет смысл и звучит как колокольчик - вы должны увидеть гораздо более предсказуемый счетчик строк, когда ваш размер строки фиксирован. Попробуйте это на столе без столбцов переменной длины или обнуляемых.

Фактически, я просто использовал это, чтобы доказать теорию о том, как использовать его для обновления (вероятно, вас подстегнул тот же вопрос, что и у меня), и выбор TABLESAMPLE (50000 ROWS) фактически затронул 49 849 строк.

Error: User Rate Limit Exceeded Rango
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededTABLESAMPLEError: User Rate Limit Exceeded Rango
Error: User Rate Limit ExceededTOPError: User Rate Limit ExceededTABLESAMPLEError: User Rate Limit Exceeded Rango
1

Такое поведение было задокументировано ранее. Есть хорошая рецензия на этоВот.

Я считаю, что вы можете это исправить, передавая команду REPEATABLE с одним и тем же семенем каждый раз. Вот фрагмент из записи:

...you will notice that different numbers of rows are returned everytime. Without any data changing, re-running the identical query keeps giving different results. This is non -deterministic factor of TABLESAMEPLE clause. If table is static and rows are not changed what could be the reason to return different numbers of the rows to return in each execution. The factor is 10 PERCENT is not the percentages of the table rows or tables records, it is percentages of the table’s data pages. Once the sample pages of data selected, all the rows from the selected pages are returned, it will not limit the number of rows sampled from that page. Fill factor of all the pages varies depends on the data of the table. This makes script to return different row count in result set everytime it is executed. The REPEATABLE option causes a selected sample to be returned again. When REPEATABLE is specified with the same repeat_seed value, SQL Server returns the same subset of rows, as long as no changes have been made to the table. When REPEATABLE is specified with a different repeat_seed value, SQL Server will typically return a different sample of the rows in the table. .

Error: User Rate Limit Exceeded Rango
3

Из документации.

The actual number of rows that are returned can vary significantly. If you specify a small number, such as 5, you might not receive results in the sample.

http://msdn.microsoft.com/en-us/library/ms189108(v=sql.90).aspx

Error: User Rate Limit ExceededDavids LinkError: User Rate Limit Exceeded Rango

Похожие вопросы