Je connais déjà un peu la réponse à cette question, mais j'ai toujours l'impression qu'il me faut en savoir plus sur le sujet.
Ma compréhension de base est que, de manière générale, un index unique qui inclut uniquement tous les champs sur lesquels vous pouvez interroger / trier à un moment donné n'est probablement pas utile, mais j'ai vu ce type de chose. Comme dans, quelqu'un a pensé: "Eh bien, si nous plaçons tout cela dans un index, la base de données peut l'utiliser pour trouver ce dont il a besoin", sans jamais avoir vu de plan d'exécution pour certaines des requêtes en cours d'exécution.
Imaginez une table comme ça:
id int pk/uid
name varchar(50)
customerId int (foreign key)
dateCreated datetime
Je pourrais voir un seul indice , y compris les name
, customerId
et les dateCreated
champs.
Mais ma compréhension est qu'un tel index ne serait pas utilisé dans une requête comme, par exemple:
SELECT [id], [name], [customerId], [dateCreated]
FROM Representatives WHERE customerId=1
ORDER BY dateCreated
Pour une telle requête, il me semble qu'une meilleure idée serait un index incluant les champs customerId
et dateCreated
, le customerId
champ étant «premier». Cela créerait un index qui aurait les données organisées de telle manière que cette requête pourrait trouver rapidement ce dont elle a besoin - dans l'ordre dont elle a besoin.
Une autre chose que je vois, peut-être aussi souvent que la première, ce sont les index individuels sur chaque champ; ainsi, une sur chaque name
, customerId
et les dateCreated
champs.
Contrairement au premier exemple, ce type d'arrangement me semble parfois au moins partiellement utile; le plan d'exécution de la requête peut montrer qu'au moins il utilise l'index sur le customerId
pour sélectionner les enregistrements, mais il n'utilise pas l'index avec le dateCreated
champ pour les trier.
Je sais que c'est une question large, car la réponse spécifique à une requête particulière sur un ensemble particulier de tables est généralement de voir ce que le plan d'exécution dit qu'il va faire, et sinon prendre en compte les spécificités des tables et des requêtes Compte. En outre, je sais que cela dépend de la fréquence à laquelle une requête peut être exécutée, par opposition à la surcharge de maintenance d'un index particulier pour elle.
Mais je suppose que ce que je demande, c'est comme un «point de départ» général pour les index, est-ce que l'idée d'avoir des index spécifiques pour des requêtes spécifiques et fréquemment tirées et les champs dans les clauses WHERE ou ORDER BY est logique?
la source
Pour répondre à votre question d'origine, oui, les index doivent être conçus autour des requêtes , pas seulement de la table . L'ordre des champs dans l'index est d'une importance vitale. Concevoir un index unique pour être optimal pour plusieurs requêtes est plus difficile, et vous devrez faire des compromis.
En ce qui concerne votre deuxième point, oui, un tas d'index sur des champs individuels est ennuyeusement commun. Je le vois tout le temps dans mon environnement, et c'est généralement un drapeau rouge pour moi que l'équipe de développement n'a pas travaillé avec un DBA pour concevoir des index appropriés.
Ma stratégie pour concevoir des index, est d'indexer:
Donc pour votre exemple:
Je voudrais probablement concevoir un index sur (CustomerID, dateCreated) INCLUDE (id, name). Cet index de couverture signifie que la requête n'a jamais besoin d'atteindre la table d'origine, améliorant considérablement les performances.
Cependant, cet exemple est presque trop simple. Un index naïf sur juste (CustomerID) fonctionnerait presque aussi bien (en supposant que chaque client n'a qu'un seul représentant, donc une seule recherche de signet dans la table sera nécessaire). Il peut également être utile de réellement faire un index clusterisé sur (CustomerID, ID), en fonction des autres requêtes exécutées sur la table.
la source