newid () / order by funcionará, pero será muy costoso para grandes conjuntos de resultados porque tiene que generar una identificación para cada fila y luego ordenarlos.
TABLESAMPLE () es bueno desde el punto de vista del rendimiento, pero obtendrá una agrupación de resultados (se devolverán todas las filas de una página).
Para obtener una muestra aleatoria verdadera con mejor rendimiento, la mejor manera es filtrar las filas al azar. Encontré el siguiente ejemplo de código en el artículo de los Libros en pantalla de SQL Server Limitar los conjuntos de resultados mediante TABLESAMPLE :
Si realmente desea una muestra aleatoria de filas individuales, modifique su consulta para filtrar las filas al azar, en lugar de usar TABLESAMPLE. Por ejemplo, la siguiente consulta usa la función NEWID para devolver aproximadamente el uno por ciento de las filas de la tabla Sales.SalesOrderDetail:
SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(),SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
La columna SalesOrderID se incluye en la expresión CHECKSUM para que NEWID () evalúe una vez por fila para lograr el muestreo por fila. La expresión CAST (CHECKSUM (NEWID (), SalesOrderID) y 0x7fffffff AS float / CAST (0x7fffffff AS int) se evalúa como un valor flotante aleatorio entre 0 y 1.
Cuando se ejecuta contra una tabla con 1,000,000 de filas, aquí están mis resultados:
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
Si puede salirse con la suya usando TABLESAMPLE, le dará el mejor rendimiento. De lo contrario, use el método newid () / filter. newid () / order by debería ser el último recurso si tiene un gran conjunto de resultados.