M’étant arrêté d’écrire pendant un certain temps, mais certainement pas de lire, me voilà de retour au clavier pour partager sur mon sujet préféré : l’optimiseur de requêtes, et plus particulièrement l’estimation de cardinalités. En butinant des billets de blog ici et là à propos de SQL Server, je trouvais un billet détaillant le comportement des requêtes spécifiant des variables de type TABLE.
Qu’est-ce que l’estimation de cardinalités ? Pour faire très court, c’est l’ensemble des règles mathématiques qui permettent à SQL Server d’avoir une idée assez précise du nombre de lignes qu’il aura à traiter lors de l’exécution d’une requête. C’est avec ce calcul-là qu’il sélectionne les algorithmes de jointure, de regroupement, l’ordre et la façon d’accéder aux tables, et bien d’autres choses encore. Bien sûr, ces choix varient suivant le volume de données à traiter. On le comprend donc, c’est un sujet très important, puisqu’il impacte directement les performances de l’exécution de nos chères (parfois en IO et temps CPU !) requêtes.
Alors vous allez me dire, crevant d’impatience : « bon d’accord, mais il le sort de son chapeau magique ce calcul ? » : au risque de vous décevoir, non. Dès lors qu’on soumet une requête qui filtre une table par une colonne, ou l’utilise dans une jointure, un regroupement, alors par défaut, le moteur crée automatiquement des objets de statistique. C’est à dire qu’il va échantillonner les données des colonnes des tables participant à la requête pour évaluer la distribution des données dans les colonnes (et index) de ces tables. Fort de ces informations, il peut alors réaliser le fameux calcul. Bref, ce sont des mathématiques
L’auteur du billet en question partageait sur le fait que par défaut, SQL Server estime qu’il n’y a qu’une seule ligne dans une variable de type TABLE. Ceci s’explique par le fait que SQL Server ne maintient pas d’objet de statistique sur les variables de type TABLE (pour les curieux, il le fait néanmoins sur les tables temporaires). Quand on sait l’usage qui est fait des variables de type TABLE dans les applications, il est évident qu’il arrive rarement que ces tables ne soient en charge que d’une seule ligne; de là des performances qui ne sont pas toujours en adéquation avec le volume de données à traiter.
Voyons le comportement par défaut du moteur à l’aide de la base de données AdventureWorks2012 :
Lire la suite →