Comment interprétez-vous le plan d'explication d'une requête?

88

Lorsque vous essayez de comprendre comment une instruction SQL s'exécute, il est parfois recommandé de consulter le plan d'explication. Quel est le processus à suivre pour interpréter (donner un sens) à un plan d'explication? Qu'est-ce qui devrait ressortir comme: "Oh, cela fonctionne à merveille?" contre "Oh non, ce n'est pas juste."

lbalazscs
la source

Réponses:

80

Je frémis chaque fois que je vois des commentaires indiquant que les tablescans complètes sont mauvaises et que l'accès aux index est bon. Les analyses complètes de table, les analyses de plage d'index, les analyses rapides d'index complet, les boucles imbriquées, les jointures de fusion, les jointures de hachage, etc. sont simplement des mécanismes d'accès qui doivent être compris par l'analyste et combinés à une connaissance de la structure de la base de données et du but d'une requête dans afin de parvenir à une conclusion significative.

Une analyse complète est tout simplement le moyen le plus efficace de lire une grande partie des blocs d'un segment de données (une table ou une (sous) partition de table), et, bien qu'elle puisse souvent indiquer un problème de performances, ce n'est que dans le contexte s'il s'agit d'un mécanisme efficace pour atteindre les objectifs de la requête. En tant qu'entrepôt de données et spécialiste de la BI, mon indicateur d'avertissement numéro un pour les performances est une méthode d'accès basée sur un index et une boucle imbriquée.

Donc, pour le mécanisme de lecture d'un plan d'explication, la documentation Oracle est un bon guide: http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/ex_plan.htm#PFGRF009

Lisez également le Guide de réglage des performances.

Ayez également un google pour le "retour de cardinalité", une technique dans laquelle un plan d'explication peut être utilisé pour comparer les estimations de cardinalité à différentes étapes d'une requête avec les cardinalités réelles rencontrées lors de l'exécution. Wolfgang Breitling est l'auteur de la méthode, je crois.

Donc, en bout de ligne: comprendre les mécanismes d'accès. Comprenez la base de données. Comprenez l'intention de la requête. Évitez les règles empiriques.

David Aldridge
la source
5
Je savais que c'était toi après les 9 premiers mots. C'est comme "nom de cette chanson" ... Je peux identifier un message de Dave A en n mots ou moins ...
Je chipoterais un peu avec votre utilisation de "grand" ... parfois les données peuvent être si mal regroupées autour de vos colonnes d'index qu'un FTS effectuerait une analyse d'index même pour 10% des lignes ...
1
Sur les 10% - absolument. Si vous avez 200 lignes par bloc et que vous recherchez 0,5% des lignes, vous devrez théoriquement accéder à 100% des blocs pour obtenir toutes les valeurs de toute façon, donc cela devient encore plus extrême que 10%.
David Aldridge
5

Les deux exemples ci-dessous montrent un scan FULL et un scan FAST à l'aide d'un INDEX.

Il est préférable de vous concentrer sur votre coût et votre cardinalité. En regardant les exemples, l'utilisation de l'index réduit le coût d'exécution de la requête.

C'est un peu plus compliqué (et je n'ai pas de contrôle à 100%), mais fondamentalement, le coût est fonction du coût du processeur et des E / S, et la cardinalité est le nombre de lignes qu'Oracle s'attend à analyser. Réduire ces deux éléments est une bonne chose.

N'oubliez pas que le coût d'une requête peut être influencé par votre requête et le modèle d'optimisation Oracle (par exemple: COST, CHOOSE, etc.) et la fréquence à laquelle vous exécutez vos statistiques.

Exemple 1:

SCAN http://docs.google.com/a/shanghainetwork.org/File?id=dd8xj6nh_7fj3cr8dx_b

Exemple 2 utilisant des index:

INDEX http://docs.google.com/a/fukuoka-now.com/File?id=dd8xj6nh_9fhsqvxcp_b

Et comme déjà suggéré, faites attention à TABLE SCAN. Vous pouvez généralement les éviter.

Mark Nold
la source
Euh, le mode Règle n'a pas de coûts ... donc je suppose que votre déclaration est correcte d'une sorte de manière la plus absolue, mais je dirais que c'est fondamentalement inexact. Si vous dites CHOISISSEZ, vous pourriez obtenir le RBO ou le CBO. CBO est le seul à calculer un coût.
4

Rechercher des choses comme des analyses séquentielles peut être quelque peu utile, mais la réalité est dans les chiffres ... sauf lorsque les chiffres ne sont que des estimations! Ce qui est généralement beaucoup plus utile que de regarder un plan de requête , c'est de regarder l' exécution réelle . Dans Postgres, c'est la différence entre EXPLAIN et EXPLAIN ANALYZE. EXPLAIN ANALYZE exécute réellement la requête et obtient des informations de synchronisation réelles pour chaque nœud. Cela vous permet de voir ce qui se passe réellement , au lieu de ce que le planificateur pense qu'il va se passer. Plusieurs fois, vous constaterez qu'une analyse séquentielle n'est pas du tout un problème, mais plutôt quelque chose d'autre dans la requête.

L'autre clé est d'identifier quelle est l'étape coûteuse réelle. De nombreux outils graphiques utilisent des flèches de différentes tailles pour indiquer le coût des différentes parties du plan. Dans ce cas, recherchez simplement les marches comportant des flèches fines et une flèche épaisse qui part. Si vous n'utilisez pas d'interface graphique, vous devrez surveiller les chiffres et chercher où ils deviennent soudainement beaucoup plus grands. Avec un peu de pratique, il devient assez facile de repérer les problèmes.

décibel
la source
3

Vraiment pour des problèmes comme ceux-ci, la meilleure chose à faire est ASKTOM . En particulier, sa réponse à cette question contient des liens vers le document Oracle en ligne, où un grand nombre de ces types de règles sont expliquées.

Une chose à garder à l'esprit, c'est que les plans d'explication sont vraiment les meilleures suppositions.

Ce serait une bonne idée d'apprendre à utiliser sqlplus et d'expérimenter la commande AUTOTRACE. Avec quelques chiffres précis, vous pouvez généralement prendre de meilleures décisions.

Mais vous devriez ASKTOM. Il sait tout ça :)

EvilTeach
la source
2

La sortie de l'explication vous indique la durée de chaque étape. La première chose à faire est de trouver les étapes qui ont pris du temps et de comprendre ce qu'elles signifient. Des choses comme une analyse séquentielle vous indiquent que vous avez besoin de meilleurs index - c'est surtout une question de recherche sur votre base de données et votre expérience particulières.

Tom Leys
la source
2

Un "Oh non, ce n'est pas juste" se présente souvent sous la forme d'une analyse de table . Les analyses de table n'utilisent aucun index spécial et peuvent contribuer à la purge de tout élément utile dans les caches mémoire. Dans PostgreSQL, par exemple, vous trouverez que cela ressemble à ceci.

Seq Scan on my_table  (cost=0.00..15558.92 rows=620092 width=78)

Parfois, les analyses de table sont idéales, par exemple, en utilisant un index pour interroger les lignes. Cependant, c'est l'un de ces modèles de drapeau rouge que vous semblez rechercher.

enveloppe convexe
la source
2
(Complet) Les analyses de table ne purgent pas nécessairement le cache mémoire.
a_horse_with_no_name
2

En gros, vous jetez un œil à chaque opération et voyez si les opérations «ont du sens» compte tenu de votre connaissance de la façon dont elles devraient pouvoir fonctionner.

Par exemple, si vous joignez deux tables, A et B sur leurs colonnes respectives C et D (AC = BD), et que votre plan affiche une analyse d'index cluster (terme SQL Server - pas sûr du terme oracle) sur la table A, puis une boucle imbriquée se joint à une série de recherches d'index en cluster sur la table B, vous pourriez penser qu'il y avait un problème. Dans ce scénario, vous pouvez vous attendre à ce que le moteur effectue une paire d'analyses d'index (sur les index sur les colonnes jointes) suivies d'une jointure par fusion. Une enquête plus approfondie peut révéler de mauvaises statistiques poussant l'optimiseur à choisir ce modèle de jointure ou un index qui n'existe pas réellement.

Jonathan Rupp
la source
1

regardez le pourcentage de temps passé dans chaque sous-section du plan et considérez ce que fait le moteur. par exemple, s'il scanne une table, envisagez de mettre un index sur le (s) champ (s) qui recherche

Steven A. Lowe
la source
1

Je recherche principalement des analyses d'index ou de table. Cela me dit généralement qu'il me manque un index sur une colonne importante qui se trouve dans l'instruction where ou join.

Depuis http://www.sql-server-performance.com/tips/query_execution_plan_analysis_p1.aspx :

Si vous voyez l'un des éléments suivants dans un plan d'exécution, vous devez les considérer comme des signes avant-coureurs et rechercher d'éventuels problèmes de performances. Chacun d'eux est loin d'être idéal du point de vue de la performance.

* Index or table scans: May indicate a need for better or  additional indexes.
* Bookmark Lookups: Consider changing the current clustered index,
  consider using a covering index, limit
  the number of columns in the SELECT
  statement.
* Filter: Remove any functions in the WHERE clause, don't include wiews
  in your Transact-SQL code, may need
  additional indexes.
* Sort: Does the data really need to be sorted? Can an index be used to
  avoid sorting? Can sorting be done at
  the client more efficiently? 

Il n'est pas toujours possible de les éviter, mais plus vous pourrez les éviter, plus les performances des requêtes seront rapides.

dpollock
la source
1
Les analyses de table ne sont pas toutes mauvaises - en fonction du nombre d'enregistrements renvoyés / traités à partir de la table, une analyse complète de la table peut être plus rapide qu'une analyse d'index (si vous allez quand même ramener les enregistrements, vous ferez une analyse d'index et une lecture complète du tableau - 2 étapes au lieu de 1).
ScottCher
-7

Règles de base

(vous voudrez probablement aussi lire les détails:

Mauvais

Scans de table de plusieurs grandes tables

Bien

Utilisation d'un index unique
comprend tous les champs obligatoires

Victoire la plus courante

Dans environ 90% des problèmes de performances que j'ai rencontrés, la solution la plus simple consiste à diviser une requête avec beaucoup (4 ou plus) de tables en 2 requêtes plus petites et une table temporaire.

UN J.
la source
2
Les balayages de table sont trop souvent considérés comme de mauvaises choses et c'est au départ ce sur quoi les personnes inexpérimentées se concentrent. Cela dépend fortement du nombre d'enregistrements renvoyés à partir de cette table, il existe un seuil à partir duquel il est plus rapide de faire une analyse complète de la table plutôt qu'une recherche d'index.
ScottCher
8
Évalué pour les conseils scandaleux. 90% des problèmes de performances ne sont PAS résolus par les tables temporaires et le fractionnement d'une requête. Dans quel monde vis-tu?!
TheSoftwareJedi
@Jedi, je vis dans un monde où les indéces ont généralement raison et les bases de données sont assez bien structurées. Je serais cependant intéressé de lire votre réponse.
AJ.