Voici un petit papier pour comparer les mots-clés TOP et TABLESAMPLE, le TOP étant dans les faits trop souvent utilisé là où l’on devrait utiliser TABLESAMPLE…
Il s’agira ici de comparer à la fois la syntaxe d’utilisation, les effets et aussi les performances.
Les exemples présentés ici s’appuieront sur la base AdventureWorksDW2012, disponible sur le site Codeplex.
Du point de vue de la syntaxe, la clause TOP se positionne entre le SELECT et le FROM.
select top 10 PERCENT * from dbo.FactProductInventory
Au niveau du plan d’exécution, on « subit » l’index choisi par le moteur (ici l’index clustered car on a un SELECT * qui récupère donc toutes les colonnes), et on récupère les dix premiers pourcents. Cela donne le plan suivant :
A noter que, comme l’index clustered est pris dans l’ordre, on récupère les premiers enregistrements, ce qui n’est pas nécessairement idéal si le besoin est d’avoir un aperçu général du contenu de la table.
A l’inverse, la clause TABLESAMPLE se positionne après la table, telle une option de forçage d’index ou de type d’isolation de verrous.
select * from dbo.FactProductInventory tablesample (10 PERCENT)
Son fonctionnement est totalement différent. Il s’agit ici de regarder, sur l’index choisi (ici encore il s’agira de l’index clustered), combien de pages de 8Ko sont occupées, et d’en piocher 10%, au hasard (pas forcément consécutives). A noter aussi qu’il ne peut être question pour TableSample que de pourcentage, contrairement à Top qui peut permettre de récupérer un nombre exact de lignes.
Du point de vue de la validité de l’échantillonage, on est nécessairement bien meilleur, car même si l’on a des blocs de données adjacentes, ces blocs sont pris au hasard dans le lot et qui plus est arrivent en ordre dispersé.
Au niveau du plan d’exécution, même si l’on a là encore ce qui apparaît comme un parcours complet d’index (index scan), il n’en est en fait rien. Même si c’est bien cet index qui est consommé, il ne l’est que de manière très parcellaire, seulement quelques pages sont récupérées deci-delà.
Point très important pour le TableSample : le nombre de lignes retournées n’est pas, contrairement à ce qui est le cas pour le TOP, exactement égal au pourcentage demandé par rapport au nombre total de lignes de la table. Le nombre de pages est bien le dixième du nombre total, mais suivant le remplissage de chaque page (taille des enregistrements, fragmentation, …), on ne peut pas garantir que l’on aura toujours le même nombre d’éléments retournés.
Par contre, en termes de performances, le TableSample surclasse très nettement le Top, qui est lui obligé de mettre en place tout un processus lourd de comptage des enregistrements, là où le TableSample se contentera de renvoyer sans autre forme de procès les données des pages sélectionnées.
A noter au passage que ces deux mots clés peuvent être combinés, pour essayer de gommer quelques défauts de l’un ou de l’autre. Mais en fait, chacun correspond à un besoin bien précis, et il suffira donc de savoir quel est notre besoin propre pour choisir la syntaxe adéquate.