для SQL Server
newid () / order by будет работать, но будет очень дорого для больших наборов результатов, потому что он должен генерировать id для каждой строки, а затем сортировать их.
TABLESAMPLE () - это хорошо с точки зрения производительности, но вы получите совокупность результатов (будут возвращены все строки на странице).
Для более эффективной работы истинной случайной выборки лучшим способом является случайная фильтрация строк. Я нашел следующий пример кода в электронной документации по SQL Server Ограничение наборов результатов с помощью TABLESAMPLE :
Если вы действительно хотите случайную выборку
отдельные строки, измените ваш запрос на
отфильтровывать строки случайным образом, а не
используя TABLESAMPLE. Например,
следующий запрос использует NEWID
функция для возврата примерно одного
процентов строк
Таблица Sales.SalesOrderDetail:
SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(),SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
Столбец SalesOrderID включен в
выражение CHECKSUM так, чтобы
NEWID () оценивается один раз в строке
достичь выборки для каждого ряда.
Выражение CAST (CHECKSUM (NEWID (),
SalesOrderID) & 0x7fffffff AS float /
CAST (0x7fffffff AS int) оценивается как
случайное значение с плавающей точкой от 0 до 1.
Когда я запускаю таблицу с 1 000 000 строк, вот мои результаты:
SET STATISTICS TIME ON
SET STATISTICS IO ON
/* newid()
rows returned: 10000
logical reads: 3359
CPU time: 3312 ms
elapsed time = 3359 ms
*/
SELECT TOP 1 PERCENT Number
FROM Numbers
ORDER BY newid()
/* TABLESAMPLE
rows returned: 9269 (varies)
logical reads: 32
CPU time: 0 ms
elapsed time: 5 ms
*/
SELECT Number
FROM Numbers
TABLESAMPLE (1 PERCENT)
/* Filter
rows returned: 9994 (varies)
logical reads: 3359
CPU time: 641 ms
elapsed time: 627 ms
*/
SELECT Number
FROM Numbers
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), Number) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
Если вам удастся избежать использования TABLESAMPLE, это даст вам наилучшую производительность. В противном случае используйте метод newid () / filter. newid () / order by должен быть последним средством, если у вас большой набор результатов.