Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment optimiser les requêtes dans une base de données - Les bases

Vous devez faire une recherche pour chaque condition où et pour chaque jointure... à condition. Les deux fonctionnent de la même manière.

Supposons que nous écrivions

select name
from customer
where customerid=37;

D'une manière ou d'une autre, le SGBD doit trouver l'enregistrement ou les enregistrements avec customerid=37. S'il n'y a pas d'index, la seule façon de le faire est de lire chaque enregistrement de la table en comparant l'ID client à 37. Même lorsqu'il en trouve un, il n'a aucun moyen de savoir qu'il n'y en a qu'un, il doit donc continuer à chercher autres.

Si vous créez un index sur customerid, le SGBD a des moyens de rechercher l'index très rapidement. Ce n'est pas une recherche séquentielle, mais, selon la base de données, une recherche binaire ou une autre méthode efficace. Exactement comment n'a pas d'importance, acceptez que c'est beaucoup plus rapide que séquentiel. L'index l'amène ensuite directement à l'enregistrement ou aux enregistrements appropriés. De plus, si vous spécifiez que l'index est "unique", alors la base de données sait qu'il ne peut y en avoir qu'un, donc elle ne perd pas de temps à chercher une seconde. (Et le SGBD vous empêchera d'en ajouter une seconde.)

Considérez maintenant cette requête :

select name
from customer
where city='Albany' and state='NY';

Maintenant, nous avons deux conditions. Si vous avez un index sur un seul de ces champs, le SGBD utilisera cet index pour trouver un sous-ensemble d'enregistrements, puis effectuera une recherche séquentielle dans ceux-ci. Par exemple, si vous avez un index sur l'état, le SGBD trouvera rapidement le premier enregistrement pour NY, puis recherchera séquentiellement city='Albany', et arrêtera de chercher lorsqu'il atteindra le dernier enregistrement pour NY.

Si vous avez un index qui inclut les deux champs, c'est-à-dire "créer un index sur le client (état, ville)", alors le SGBD peut immédiatement zoomer sur les bons enregistrements.

Si vous avez deux index distincts, un sur chaque champ, le SGBD appliquera diverses règles pour décider quel index utiliser. Encore une fois, la façon exacte dont cela est fait dépend du SGBD particulier que vous utilisez, mais fondamentalement, il essaie de conserver des statistiques sur le nombre total d'enregistrements, le nombre de valeurs différentes et la distribution des valeurs. Ensuite, il recherchera séquentiellement dans ces enregistrements ceux qui satisfont à l'autre condition. Dans ce cas, le SGBD observerait probablement qu'il y a beaucoup plus de villes qu'il n'y a d'états, donc en utilisant l'index des villes, il peut rapidement zoomer sur les enregistrements 'Albany'. Ensuite, il les recherchera séquentiellement, vérifiant l'état de chacun par rapport à "NY". Si vous avez des enregistrements pour Albany, Californie, ceux-ci seront ignorés.

Chaque jointure nécessite une sorte de recherche.

Disons que nous écrivons

select customer.name
from transaction
join customer on transaction.customerid=customer.customerid
where transaction.transactiondate='2010-07-04' and customer.type='Q';

Maintenant, le SGBD doit décider quelle table lire en premier, sélectionner les enregistrements appropriés à partir de là, puis trouver les enregistrements correspondants dans l'autre table.

Si vous aviez un index sur transaction.transactiondate et customer.customerid, le meilleur plan serait probablement de trouver toutes les transactions avec cette date, puis pour chacune d'entre elles, de trouver le client avec le customerid correspondant, puis de vérifier que le client a le bon type.

Si vous n'avez pas d'index sur customer.customerid, le SGBD pourrait rapidement trouver la transaction, mais pour chaque transaction, il devrait alors rechercher séquentiellement la table des clients à la recherche d'un customerid correspondant. (Ce serait probablement très lent.)

Supposons plutôt que les seuls index dont vous disposez se trouvent sur transaction.customerid et customer.type. Ensuite, le SGBD utiliserait probablement un plan complètement différent. Il analyserait probablement la table des clients pour tous les clients avec le type correct, puis pour chacun d'entre eux, trouverait toutes les transactions pour ce client et les rechercherait séquentiellement pour la bonne date.

La clé la plus importante de l'optimisation est de déterminer quels index seront vraiment utiles et de créer ces index. Les index supplémentaires inutilisés sont un fardeau pour la base de données car il faut du travail pour les maintenir, et s'ils ne sont jamais utilisés, c'est un effort inutile.

Vous pouvez dire quels index le SGBD utilisera pour une requête donnée avec la commande EXPLAIN. Je l'utilise tout le temps pour déterminer si mes requêtes sont bien optimisées ou si je dois créer des index supplémentaires. (Lisez la documentation sur cette commande pour une explication de sa sortie.)

Mise en garde :rappelez-vous que j'ai dit que le SGBD gardait des statistiques sur le nombre d'enregistrements et le nombre de valeurs différentes, etc. dans chaque table. EXPLAIN peut vous donner aujourd'hui un plan complètement différent de celui d'hier si les données ont changé. Par exemple, si vous avez une requête qui joint deux tables et que l'une de ces tables est très petite tandis que l'autre est grande, elle sera biaisée pour lire d'abord la petite table, puis trouver les enregistrements correspondants dans la grande table. L'ajout d'enregistrements dans une table peut changer la taille de celle-ci, et ainsi conduire le SGBD à modifier son plan. Ainsi, vous devriez essayer de faire EXPLAINS sur une base de données avec des données réalistes. L'exécution sur une base de données de test avec 5 enregistrements dans chaque table a beaucoup moins de valeur que l'exécution sur une base de données en direct.

Eh bien, il y a encore beaucoup à dire, mais je ne veux pas écrire un livre ici.