TABLESAMPLE, une alternative à ORDER BY NEWID()

Juste un petit post pour présenter une instruction TSQL utile à connaître. Quand vous voulez obtenir un jeu d’enregistrement d’une table de façon aléatoire, il était commode d’utiliser la fonction NEWID (qui génère un GUID) dans une clause ORDER BY.

select top 1000 * from person.contact order by newid()

Le problème c’est que l’on arrive vite à des performances médiocres, surtout avec des volumes de données importants. L’instruction TABLESAMPLE sert à récupérer un échantillon d’enregistrements de façon aléatoire et un petit bench nous montre que cette technique enterre la première.

select * from person.contact tablesample (1000 rows)

Remarques

L’instruction TABLESAMPLE ne ramène pas le nombre exact d’enregistrement : c’est parce que le moteur de requêtes choisit aléatoirement des pages (8ko) de l’index clustered. Et une fois une page choisie, il remonte tous les enregistrements qui s’y trouvent. En fonction de la fragmentation et de la taille de l’enregistrement, vous aurez plus ou moins de lignes remontées.

L’instruction TABLESAMPLE fait toujours un SCAN dans le plan d’exécution : c’est parce que le requêteur attribue une valeur aléatoire à chaque page de l’index clustered ou HEAP et choisit ensuite les pages en fonctions de ces valeurs. Le scan est donc obligatoire.

 

PS : merci à Matthieu de Bordeaux de m’en avoir parlé

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s