Ключом здесь является функция NEWID, которая генерирует глобально уникальный идентификатор (GUID) в памяти для каждой строки.По определению, GUID является уникальным и довольно случайным;поэтому, когда вы сортируете по этому GUID с предложением ORDER BY, вы получаете случайный порядок строк в таблице.Взяв верхние 10 процентов (или любой другой процент), вы получите случайную выборку строк в таблице.
Предложен запрос NEWID;это просто и работает очень хорошо для небольших столов.Однако запрос NEWID имеет большой недостаток, когда вы используете его для больших таблиц.Предложение ORDER BY приводит к копированию всех строк в таблице в базу данных tempdb, где они сортируются.Это вызывает две проблемы: Операция сортировки обычно связана с высокой стоимостью.Сортировка может использовать много дискового ввода-вывода и может выполняться в течение длительного времени.В худшем случае в базе данных tempdb может не хватить места.В лучшем случае tempdb может занимать большой объем дискового пространства, которое никогда не будет возвращено без команды сжатия вручную.Вам нужен способ случайного выбора строк, который не будет использовать базу данных tempdb и не станет намного медленнее по мере увеличения таблицы.Вот новая идея о том, как это сделать:
SELECT * FROM master..spt_values
WHERE (ABS(CAST(
(BINARY_CHECKSUM(*) *
RAND()) as int)) % 100) < 10
Основная идея этого запроса заключается в том, что мы хотим сгенерировать случайное число от 0 до 99 для каждой строки в таблице, а затем выбрать всеиз тех строк, случайное число которых меньше значения указанного процента.В этом примере мы хотим, чтобы приблизительно 10 процентов строк были выбраны случайным образом;поэтому мы выбираем все строки, чье случайное число меньше 10.