Quand est-il préférable de créer des statistiques au lieu de créer un index?


38

J'ai trouvé beaucoup d'informations sur ce qui STATISTICS sont: comment ils sont maintenus, comment ils peuvent être créés manuellement ou automatiquement à partir des requêtes ou des index, et ainsi de suite. Mais, je suis incapable de trouver une information ou de conseil « meilleures pratiques » en ce qui concerne quandpour les créer: quelles situations profitent davantage d'un objet STATISTICS créé manuellement que d'un index. J'ai vu des statistiques filtrées créées manuellement aidant les requêtes sur des tables partitionnées (car les statistiques créées pour les index couvrent la totalité du tableau et ne sont pas détaillées par partition - brillaint!), Mais il doit sûrement y avoir d'autres scénarios pouvant tirer parti d'un objet statistiques tout en ne nécessitant pas le détail d'un index, ni le coût du maintien de l'indice ou l'augmentation des chances de blocage / blocage.

@JonathanFite, dans un commentaire, a mentionné une distinction entre les index et les statistiques:

Les index aideront SQL à trouver les données plus rapidement en créant des recherches triées différemment de la table elle-même. Les statistiques aident SQL à déterminer la quantité de mémoire / les efforts nécessaires pour satisfaire la requête.

C'est une bonne information, surtout parce que cela m'aide à clarifier ma question:

Comment le fait de savoir ce (ou toute autre information technique sur le ce s et comment s liés aux comportements et la nature de STATISTICS) aident à déterminer quand choisir CREATE STATISTICSplus CREATE INDEX, en particulier lors de la création d' un index va créer l'associée STATISTICSobjet? Quel scénario serait mieux servi en ne disposant que des informations STATISTICS et en ne disposant pas de l'indice?

Il serait extrêmement utile, si possible, d’avoir un exemple concret de scénario dans lequel l’ STATISTICSobjet convient mieux qu’un objet INDEX.


Étant donné que je suis un penseur / penseur visuel, j’ai pensé qu’il serait peut-être utile de voir les différences entre STATISTICSet INDEXes, côte à côte, comme un moyen possible de déterminer STATISTICSle meilleur choix.

Thingy           PROs                             CONs
-------          ----------                       -------------------
INDEX            * Can help sorts.                * Takes up space.
                 * Contains data (can             * Needs to be maintained (extra I/O).
                   "cover" a query).              * More chances for blocking / dead-locks.

STATISTICS       * Takes up very little space.    * Cannot help sorts.
                 * Lighter maintenance / won't    * Cannot "cover" queries.
                   slow down DML operations.
                 * Does not increase chances
                   of blocking / dead-locks.

Voici quelques ressources que j'ai trouvées en cherchant ceci, une qui pose même la même question, mais elle n'a pas reçu de réponse:

Index SQL Server vs statistique

Questions sur les statistiques de SQL Server que nous étions trop timides à poser

Statistiques. Les histogrammes multicolonnes sont-ils possibles?

** Pour être clair, je n'ai pas de réponse à cela et je cherche en fait à obtenir les commentaires de quelques personnes, espérons-le, pour fournir ce qui semble étrangement manquer d'informations ici.


1
Les index aideront SQL à trouver les données plus rapidement en créant des recherches triées différemment de la table elle-même. Les statistiques aident SQL à déterminer la quantité de mémoire / les efforts nécessaires pour satisfaire la requête.
Jonathan Fite

@ JonathanFite Merci pour ce commentaire. Je l'ai incorporé à ma question :).
Solomon Rutzky

Après le commentaire de @ JonathanFite, il semblerait que les statistiques sont les meilleures pour augmenter les performances sur les systèmes / tables / modèles de requête ad hoc, tandis que les index sont préférables pour les modèles de requête prévisibles. Je pense que ceci est plus une question qu'une déclaration.
Dave

Réponses:


19

Votre question tourne autour - Quand est-ce une bonne chose de créer simplement des statistiques contre un index (qui crée des statistiques).

De mes notes internes au serveur SQL (classe SQLSkills - IE1 et IE2) et au livre interne de SQL Server , voici ma compréhension limitée :

Les statistiques SQL Server ne sont rien d'autre que des objets système contenant des informations essentielles sur les valeurs de clé d'index et les valeurs de colonne standard.

SQL Server utilise un modèle basé sur les coûts pour choisir le plus rapidement possible un plan d'exécution "correct". L'estimation de la cardanilité (l'estimation du nombre de lignes à traiter à chaque étape de l'exécution de la requête) est le facteur le plus important de l'optimisation de la requête, qui affecte actuellement la stratégie de jointure, les besoins en mémoire, la sélection du thread de travail ainsi que le choix des index lors de l'accès aux données. .

SQL Server n'utilisera pas d'index non cluster lorsqu'il estime qu'un grand no. d’opérations de mise en boucle KEY ou RID seront nécessaires, de sorte qu’il conserve des statistiques sur les index (et sur les colonnes), ce qui facilitera ces estimations.

Il y a 2 choses importantes à propos des statistiques:

  1. L'histogramme stocke les informations sur la distribution des données pour la colonne de statistiques (index) la plus à gauche UNIQUEMENT. Il stocke également des informations sur la densité multi-colonnes des valeurs de clé. En gros, l'histogramme enregistre la distribution des données pour la colonne de statistiques la plus à gauche uniquement.

  2. SQL Server conservera 200 histogrammes au maximum, quelle que soit la taille de la table. Les intervalles couverts par chaque étape de l'histogramme augmentent avec la taille du tableau, ce qui conduit à des statistiques "moins précises" pour les grands tableaux.

    N'oubliez pas que la sélectivité d'index est une métrique inversement proportionnelle à la densité, c'est-à-dire que plus une colonne a de valeurs uniques, plus sa sélectivité est élevée.

Lorsque des requêtes particulières ne s'exécutent pas très souvent, vous pouvez choisir de créer des statistiques au niveau des colonnes plutôt qu'un index. Les statistiques au niveau des colonnes aident Query Optimizer à trouver de meilleurs plans d'exécution, même si ces plans d'exécution sont sous-optimaux en raison des analyses d'index impliquées. Dans le même temps, les statistiques n’ajoutent pas de surcharge lors des opérations de modification des données et permettent d’éviter la maintenance des index. Cette approche ne fonctionne que pour les requêtes rarement exécutées.

Référer :

Remarque: une personne comme Paul White ou Aaron Bertrand peut ajouter de la couleur à votre bonne question .


"SQL Server n'utilisera pas d'index non clusterisés lorsqu'il estimera qu'un grand nombre d'opérations de bouclage KEY ou RID seront nécessaires" Ainsi, le QO peut-il utiliser l'objet stats en fonction d'un index indépendant de celui-ci? Cela signifie que si l'index n'est pas optimal, mais que la colonne de tête est dans la requête, les statistiques sont toujours pertinentes. Alors, seraient-ils utilisés? Ou bien cette information implique-t-elle qu'il peut y avoir des cas où un index ne serait probablement pas utilisé, mais puisque les statistiques ont toujours une valeur, il n'y a donc aucune raison réelle de créer l'index, mais simplement les statistiques?
Solomon Rutzky

8

Je dirais que vous avez besoin d'un index lorsque vous devez pouvoir limiter la quantité de données / accéder rapidement aux données correctes en fonction du ou des champs.

Vous avez besoin de statistiques lorsque l'optimiseur doit comprendre la nature des données pour pouvoir effectuer les opérations de la meilleure façon possible.

Ce que j’ai compris, les statistiques filtrées aident en cas de biais dans vos données qui affectent considérablement le plan. Par exemple, en cas de dépassement de pile, peu d’utilisateurs ont un nombre important de publications. Ainsi, vous pouvez créer des statistiques filtrées sur userId en fonction du nom d'utilisateur. SQL Server doit alors savoir que lorsque ce nom d'utilisateur est dans la requête, il s'agit de l'ID utilisateur qu'il obtiendra et qu'il devrait pouvoir déterminer Le champ indexé dans la table posts aura un grand nombre de lignes avec cet identifiant car l'histogramme y existe. Avec des moyennes, ce n'est pas possible.


1
Bonjour et merci d'avoir répondu. Alors, quand aurais-je besoin / de la volonté de l'optimiseur de mieux comprendre la nature des données, sans toutefois limiter ces données, ni vouloir y accéder plus rapidement, ou en avoir besoin pour "couvrir" la requête? Idem pour votre exemple d'index filtré. Je comprends ce que vous dites en termes de séparation des cas extrêmes des moyennes, mais pourquoi les statistiques filtrées seraient-elles meilleures qu'un index filtré sur les mêmes champs? C'est la distinction que j'essaie de faire.
Solomon Rutzky

Comme dans l'exemple, vous ne pouvez pas créer d'index filtré sur le nom d'utilisateur dans la table posts, car il n'y existe pas. Vous pouvez le créer en fonction de l'ID utilisateur, mais ce n'est pas dans la clause where.
James Z

Mais ne serait-il pas UserIDdans la condition JOIN, même si ce n'est pas dans WHERE? Et cela ne suffirait-il pas pour choisir un index filtré?
Solomon Rutzky

@srutzky Peut-être plus vraisemblablement dans les versions les plus récentes, mais en général, je ne m'appuierais pas dessus ... dans la plupart des cas, les prédicats doivent correspondre exactement. J'oublie que s'ils résolvaient cela, mais à un moment donné, un index filtré WHERE BitColumn = 0ne serait pas sélectionné pour une simple requête WHERE BitColumn <> 1. (Et pour être clair, la colonne de bits n'était pas annulable.) Je pense qu'il y a eu des cas similaires, comme IntColumn > 10ne pas faire correspondre IntColumn >= 11.
Aaron Bertrand

Les index filtrés ne peuvent pas être utilisés s'il est possible que la prochaine fois que quelqu'un utilise les plans, l'index filtré ne convient plus. Je ne pense pas que des jointures utilisant un index filtré Même les variables ne peuvent pas être utilisées car la prochaine fois, la valeur pourrait ne pas être appropriée.
James Z

4

Livre de formation 70-461 d'Itzik Ben-Gan

Il n'y a que quelques raisons possibles pour créer des statistiques manuellement. Par exemple, un prédicat de requête contient plusieurs colonnes ayant des relations entre colonnes; les statistiques sur les colonnes multiples peuvent aider à améliorer le plan de requête. Les statistiques sur plusieurs colonnes contiennent des densités inter-colonnes qui ne sont pas disponibles dans les statistiques sur une colonne. Toutefois, si les colonnes se trouvent déjà dans le même index, l'objet de statistiques multicolonnes existe déjà. Vous ne devez donc pas en créer un supplémentaire manuellement.


Merci d'avoir posté ceci. Ceci répond à une partie de ma question mais laisse toujours ouverte la question suivante: Si j’ai besoin des statistiques multi-colonnes, pourquoi ne créerais-je que les STATISTIQUES au lieu de l’Index, qui inclurait les STATISTIQUES ainsi que des informations supplémentaires susceptibles d’aider la requête ( ies)?
Solomon Rutzky

1
Je pense que l'explication de Kin expliquerait davantage ce que vous recherchez. Peut-être un tas qui est fréquemment inséré, mais rarement interrogé?
Kentaro
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.