Traitement des instructions SQL
Le traitement d'une instruction SQL unique est le cas le plus simple d'exécution par SQL Server. Les étapes de traitement d'une instruction SELECT unique qui ne fait référence qu'à des tables de base locales (et non à des vues ou à des tables distantes) illustrent le processus de base.
Optimisation des instructions SELECT
Une instruction SELECT est non procédurale ; elle ne précise pas les étapes exactes à suivre par le serveur de base de données pour extraire les données demandées. Cela signifie que le serveur de base de données doit analyser l'instruction afin de déterminer la manière la plus efficace d'extraire les données demandées. Cette opération est nommée optimisation de l'instruction SELECT. Le composant qui s'en charge est l'optimiseur de requête. L'entrée dans l'optimiseur est composée de la requête, du schéma de base de données (définitions des tables et des index) et de ses statistiques. La sortie de l'optimiseur est un plan d'exécution de la requête, parfois dénommé plan de requête ou simplement plan. Le contenu d'un plan de requête est détaillé plus loin dans cette rubrique.
Les entrées et les sorties de l'optimiseur de requête pendant l'optimisation d'une instruction SELECT unique sont illustrées dans le diagramme suivant :
Une instruction SELECT ne définit que :
le format du jeu de résultats. Il est principalement spécifié dans la liste de sélection. Toutefois, d'autres clauses telles que ORDER BY et GROUP BY influencent également la syntaxe finale du jeu de résultats.
les tables contenant les données source. Elles sont spécifiées dans la clause FROM.
la manière dont les tables sont reliées de façon logique pour les besoins de l'instruction SELECT. Elle est définie dans les spécifications de jointure, qui peuvent être présentes dans la clause WHERE ou dans une clause ON à la suite de FROM.
Les conditions auxquelles doivent répondre les lignes des tables source afin de correspondre à l'instruction SELECT. Elles sont spécifiées dans les clauses WHERE et HAVING.
Un plan d'exécution de requête permet de définir :
l'ordre d'accès aux tables source.
Pour créer le jeu de résultats, le serveur de bases de données peut accéder aux tables de base selon de nombreux ordres différents. Par exemple, si l'instruction SELECT fait référence à trois tables, le serveur de base de données accédera d'abord à TableA, utilisera les données de TableA pour extraire les lignes correspondantes de TableB, puis utilisera les données de TableB pour extraire les données de TableC. Les autres séquences dans lesquelles le serveur de bases de données peut accéder aux tables sont les suivantes :
TableC, TableB, TableA ou
TableB, TableA, TableC ou
TableB, TableC, TableA ou
TableC, TableA, TableB
les méthodes utilisées pour extraire les données de chaque table.
Il existe également différentes méthodes d'accès aux données dans chaque table. Si seules quelques lignes ayant des valeurs de clés spécifiques sont nécessaires, le serveur de base de données peut utiliser un index. Si toutes les lignes de la table sont nécessaires, le serveur de base de données peut ignorer les index et procéder à une analyse de la table. Si toutes les lignes de la table sont nécessaires mais s'il existe un index dont les colonnes de clé se trouvent dans une clause ORDER BY, l'analyse d'index plutôt que l'analyse de table peut éviter un tri séparé du jeu de résultats. Dans le cas d'une table très petite, les analyses de table peuvent s'avérer plus efficaces pour quasiment tous les accès à la table.
Le processus de sélection d'un plan d'exécution parmi plusieurs possibles est appelé optimisation. L'optimiseur de requêtes est un des composants les plus importants d'un système de base de données SQL. Bien que l'optimiseur de requête puisse créer une certaine surcharge pour analyser la requête et sélectionner un plan, celle-ci est en général largement compensée par l'adoption d'un plan d'exécution efficace. Prenons l'exemple de deux entrepreneurs en bâtiment à qui l'on commande la même maison. Si l'un d'eux commence par consacrer quelques jours à planifier la construction de cette maison alors que l'autre lance immédiatement la construction sans aucune planification, il est fort probable que celui qui a pris le temps de planifier son projet finira le premier.
L'optimiseur de requête SQL Server est un optimiseur basé sur les coûts. À chaque plan d'exécution possible est associé un coût exprimé en termes de quantité de ressources informatiques utilisées. L'optimiseur de requêtes doit analyser les plans possibles et opter pour celui dont le coût estimé est le plus faible. Certaines instructions SELECT complexes disposent de milliers de plans d'exécution possibles. Dans ce cas, l'optimiseur de requêtes n'analyse pas toutes les combinaisons possibles. Il recourt alors à des algorithmes sophistiqués afin de trouver un plan d'exécution dont le coût se rapproche raisonnablement du minimum possible.
L'optimiseur de requête SQL Server choisit non seulement le plan d'exécution dont le coût en ressources est le plus faible, mais également celui qui retourne le plus rapidement les résultats à l'utilisateur moyennant un coût en ressources raisonnable. Par exemple, le traitement d'une requête en parallèle monopolise généralement davantage de ressources qu'un traitement en série, mais il est plus rapide. L'optimiseur SQL Server utilise un plan d'exécution en parallèle pour retourner les résultats si la charge du serveur n'en est pas affectée de façon rédhibitoire.
L'optimiseur de requête se base sur les statistiques de distribution lors de l'estimation du coût en ressources pour les différentes méthodes d'extraction d'informations à partir d'une table ou d'un index. Les statistiques de distribution sont conservées pour les colonnes et les index. Elles indiquent la sélectivité des valeurs dans un index ou une colonne en particulier. Par exemple, dans une table représentant des voitures, plusieurs voitures proviennent du même constructeur mais chacune a un numéro d'identification unique. Un index sur le numéro d'identification du véhicule est plus sélectif qu'un index sur le constructeur. Si les statistiques d'index ne sont pas à jour, l'optimiseur de requêtes peut ne pas effectuer le meilleur choix pour l'état actuel de la table. Pour plus d'informations sur la tenue à jour des statistiques d'index, consultez Utilisation des statistiques pour améliorer les performances des requêtes.
L'optimiseur de requête est important car il permet l'ajustement dynamique du serveur de base de données face à l'évolution de la base de données sans recourir à l'intervention d'un programmeur ou d'un administrateur de bases de données. Cela permet aux programmeurs de se concentrer sur la description du résultat final de la requête. Ils peuvent faire confiance à l'optimiseur de requête dans son choix d'un plan d'exécution efficace pour l'état de la base de données à chaque exécution de l'instruction.
Traitement d'une instruction SELECT
Les étapes permettant à SQL Server de traiter une instruction SELECT unique sont les suivantes :
L'analyseur examine l'instruction SELECT et la décompose en unités logiques telles que mots clé, expressions, opérateurs et identificateurs.
Un arbre de requêtes, également appelé arbre de séquence, est créé pour décrire les étapes logiques nécessaires à la transformation des données source au format requis par le jeu de résultats.
L'optimiseur de requête analyse plusieurs méthodes d'accès aux tables source. Il choisit ensuite la série d'étapes qui retourne les résultats le plus rapidement tout en consommant moins de ressources. L'arbre de requêtes est mis à jour pour enregistrer cette série exacte d'étapes. La version optimisée finale de l'arbre de requêtes est nommée plan d'exécution.
Le moteur relationnel lance le plan d'exécution. Pendant le traitement des étapes qui requièrent des données issues des tables de base, le moteur relationnel demande que le moteur de stockage transmette les données des ensembles de lignes demandés à partir du moteur relationnel.
Le moteur relationnel traite les données retournées du moteur de stockage dans le format défini pour le jeu de résultats et retourne ce jeu au client.
Traitement des autres instructions
Les étapes de base décrites pour le traitement d'une instruction SELECT s'appliquent également aux autres instructions SQL telles que INSERT, UPDATE et DELETE. Les instructions UPDATE et DELETE doivent toutes deux cibler l'ensemble de lignes à modifier ou à supprimer. Le processus d'identification de ces lignes est le même que celui utilisé pour identifier les lignes source qui participent au jeu de résultats d'une instruction SELECT. Les instructions UPDATE et INSERT peuvent toutes deux contenir des instructions SELECT incorporées qui fournissent les valeurs de données à mettre à jour ou à insérer.
Même les instructions DDL telles que CREATE PROCEDURE ou ALTER TABLE sont finalement réduites à une série d'opérations relationnelles sur les tables du catalogue système, voire (comme dans le cas de ALTER TABLE ADD COLUMN) sur les tables de données.