Nous commençons avec la clause where
la plus
simple et la plus commune : la recherche d'une clé primaire. Pour les
exemples de ce chapitre, nous utilisons la table EMPLOYES
qui se définie ainsi :
CREATE TABLE employes (
id_employe NUMBER NOT NULL,
prenom VARCHAR(1000) NOT NULL,
nom VARCHAR(1000) NOT NULL,
date_de_naissance DATE NOT NULL,
numero_telephone VARCHAR(1000) NOT NULL,
CONSTRAINT employes_pk PRIMARY KEY (id_employe)
)
La base de données crée automatiquement un index pour la clé
primaire. Cela signifie qu'il existe un index sur la colonne
ID_EMPLOYE
, même si nous n'avons pas exécuté de commande
create index
.
Astuce
Annexe C, « Example Schema » contient
des scripts pour
peupler la table EMPLOYES
avec des données exemples. Vous
pouvez l'utiliser pour tester les exemples dans votre propre
environnement.
Pour suivre le texte, il suffit de savoir que la table contient 1000 lignes.
La requête suivante utilise la clé primaire pour récupérer le nom d'un employé :
SELECT prenom, nom
FROM employes
WHERE id_employe = 123
La clause where
ne peut pas correspondre à
plusieurs enregistrements car la clé primaire assure l'unicité des
valeurs de la colonne ID_EMPLOYE
. La base de données n'a
pas besoin de suivre les nœuds feuilles de l'index. Il suffit de
parcourir l'arbre de l'index. Nous pouvons utiliser le
plan d'exécution pour vérifier :
- MySQL
+----+----------+-------+---------+---------+------+-------+ | id | table | type | key | key_len | rows | Extra | +----+----------+-------+---------+---------+------+-------+ | 1 | employes | const | PRIMARY | 5 | 1 | | +----+----------+-------+---------+---------+------+-------+
- Oracle
-------------------------------------------------------------- |Id |Operation | Name | Rows | Cost | -------------------------------------------------------------- | 0 |SELECT STATEMENT | | 1 | 2 | | 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYES | 1 | 2 | |*2 | INDEX UNIQUE SCAN | EMPLOYES_PK | 1 | 1 | -------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("ID_EMPLOYE"=123)
- PostgreSQL
QUERY PLAN ------------------------------------------- Index Scan using employes_pk on employes (cost=0.00..8.27 rows=1 width=14) Index Cond: (id_employe = 123::numeric)
- SQL Server
|--Nested Loops(Inner Join) |--Index Seek(OBJECT:employes_pk, | SEEK:employes.id_employe=@1 | ORDERED FORWARD) |--RID Lookup(OBJECT:employes, SEEK:Bmk1000=Bmk1000 LOOKUP ORDERED FORWARD)
Le plan d'exécution Oracle affiche un INDEX UNIQUE
SCAN
, ce qui correspond à l'opération qui ne fait que parcourir
l'arbre de l'index. Il utilise complètement la complexité logarithmique
de l'index pour trouver l'entrée très rapidement, pratiquement
indépendamment de la taille de la table.
Astuce
Le plan d'exécution (quelque fois appelé plan explain ou plan de la requête) montre les étapes réalisées par la base pour exécuter une requête SQL. L'Annexe A explique comment récupérer et lire les plans d'exécution avec d'autres bases de données.
Après avoir accédé à l'index, la base de données doit réaliser une
autre étape pour récupérer les données demandées
(
,
PRENOM
) à partir du stockage de la
table : il s'agit de l'opération NOM
TABLE ACCESS BY INDEX
ROWID
. Cette opération peut devenir un goulet d'étranglement,
comme expliqué dans la « Index lents, partie I », mais ce risque est inexistant avec un
INDEX UNIQUE SCAN
. Cette opération ne peut pas
renvoyer plus d'une entrée donc elle ne peut pas déclencher plus d'un
accès à la table. Cela signifie que les ingrédients d'une requête lente
ne sont pas présents avec un INDEX UNIQUE SCAN
.