newid () / order by fonctionnera, mais sera très coûteux pour les grands ensembles de résultats car il doit générer un identifiant pour chaque ligne, puis les trier.
TABLESAMPLE () est bon du point de vue des performances, mais vous obtiendrez un agrégat de résultats (toutes les lignes d'une page seront retournées).
Pour un véritable échantillon aléatoire plus performant, la meilleure façon est de filtrer les lignes de manière aléatoire. J'ai trouvé l'exemple de code suivant dans l'article de documentation en ligne de SQL Server Limitation des ensembles de résultats à l'aide de TABLESAMPLE :
Si vous voulez vraiment un échantillon aléatoire de lignes individuelles, modifiez votre requête pour filtrer les lignes au hasard, au lieu d'utiliser TABLESAMPLE. Par exemple, la requête suivante utilise la fonction NEWID pour renvoyer environ un pour cent des lignes de la table Sales.SalesOrderDetail:
SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(),SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
La colonne SalesOrderID est incluse dans l'expression CHECKSUM afin que NEWID () évalue une fois par ligne pour réaliser l'échantillonnage sur une ligne. L'expression CAST (CHECKSUM (NEWID (), SalesOrderID) & 0x7fffffff AS float / CAST (0x7fffffff AS int) est évaluée comme une valeur flottante aléatoire comprise entre 0 et 1.
Lorsqu'il est exécuté sur une table avec 1 000 000 lignes, voici mes résultats:
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 vous pouvez vous en sortir en utilisant TABLESAMPLE, cela vous donnera les meilleures performances. Sinon, utilisez la méthode newid () / filter. newid () / order by devrait être le dernier recours si vous avez un grand ensemble de résultats.