J'utilise SQL Server et je suis à la recherche de près le concept de recherches clés,
Donc, si vous avez une recherche clé, vous pouvez créer un index avec les colonnes "Inclure" pour couvrir les colonnes non indexées que vous avez dans l'instruction SELECT.
Par exemple,
SELECT ID, FirstName FROM OneIndex WHERE City = 'Las Vegas'
GO
Cet index comprendra une recherche clé,
CREATE NONCLUSTERED INDEX [IX_OneIndex_City] ON [dbo].[OneIndex]
(
[City] ASC
) ON [PRIMARY]
GO
Mais celui-ci enlèvera la clé de la clé,
CREATE NONCLUSTERED INDEX [IX_OneIndex_Include] ON [dbo].[OneIndex]
(
City
) INCLUDE (FirstName,ID) ON [PRIMARY]
GO
Je veux dire combien d'impact cela aura-t-il sur la performance? La recherche clé a un coût d'opérateur de 0,295969 (99%), mais qu'est-ce que cela signifie vraiment?
Comment savez-vous que vous avez besoin du deuxième indice là-bas, et à quel point est-il devenu le cas que vous essayez d'ajouter trop d'index et que cela ne vaut pas la peine?
Il me semble que certaines requêtes peuvent inclure des analyses d'index, des recherches clés et semblent toujours performer très rapidement.
Imaginez que la société de téléphone dispose d'une liste de numéros de téléphone, y compris de qui le client est le client, où ils vivent, quel est leur numéro de facturation, etc. La clé principale pourrait être le numéro de téléphone.
Ils vous donnent les pages blanches. C'est comme un indice non clusterné, qui a ordonné par nom, y compris des colonnes comme l'adresse.
Si vous voulez trouver tous les élèves du livre et que leurs adresses sont intéressées, les pages blanches sont tout ce dont vous avez besoin. Vous pouvez rapidement chercher à la Farleys (trouver le FS, etc.), puis vous avez toutes les informations dont vous avez besoin.
Mais si vous voulez leurs numéros de facturation, vous devez rechercher une recherche. Vous pouvez rapidement trouver tous les numéros de téléphone des Farleys, mais vous devez alors prendre chacune d'elles (centaines) et faire une autre recherche (recherche) dans l'index principal (cluster), celui qui est commandé par le numéro de téléphone. Chacun de ceux-ci est à peu près le même coût que la recherche de la recherche de l'éloignement, rendant les ordres de la magnitude de votre requête pire.
Et il y a un seuil. À un moment donné, la base de données se rendra compte qu'il est plus rapide de passer à chaque page de l'index en cluster, en vérifiant chaque enregistrement pour voir si cela est d'intérêt.
Sérieusement - éloignez-vous des recherches. Vos requêtes pourraient être rapides maintenant, mais ne seront probablement pas à l'échelle.
Dans le pire des cas, une requête contenant une recherche doit accéder au stockage physique des lignes nécessitant des données de colonne non couvertes par l'indice non clustered. Dans le très pire des pires cas, chaque recherche nécessitera un E/S distinct et une exécution devra attendre que la valeur de cette ligne de la seule ligne soit revenue avant de procéder. Ce scénario a généralement de graves implications de performances si la recherche doit traiter un nombre a significatif nombre de lignes.
C'est pourquoi les recherches obtiennent une telle mauvaise presse. D'autre part, considérez que la possibilité de faire des recherches a été introduite dans SQL Server 2000. Dans SQL Server 7.0, le processeur de requête ne pouvait utiliser un index non clusterisé s'il contenait tous les informations nécessaires pour satisfaire la requête ; Dans tous les autres cas, il a dû accéder aux données via un indice en cluster (le cas échéant, ou un scan de tas autrement). Si les recherches étaient toujours très mauvaises, SQL Server ne les aurait sûrement jamais présentés.
Dans SQL Server 2000+, dans laquelle nous disposons d'un indice non clusterié qui fournit des commandes utiles et/ou (la plupart des) les colonnes requises par une requête et où le nombre de recherches est susceptible d'être relativement faible, à l'aide de l'indice non clusterné et de l'exécution A Nombre limité de recherches sur la table de base est probablement la méthode d'accès disponible la moins chère (bien qu'un indice non clusterné complet puisse être moins cher encore, bien sûr).
Dans de nombreux cas, c'est juste pas pratique Pour créer autant d'index non clusters, comme il serait nécessaire d'éviter de balayer la table de base pour toutes les requêtes courantes. Une des raisons pourrait être que INSERT/UPDATE/DELETE/MERGE
La performance est plus importante que la vitesse d'interrogation (rappelez-vous que les opérations de modification de données doivent également conserver tous les index non clusters affectés). Une autre raison pourrait être un espace; Chaque index non clustere représente une copie d'un sous-ensemble des colonnes de la table de base (ou des expressions de ceux-ci) vient de trier différemment. Plusieurs copies des données signifient plus d'espace de stockage, et plus de choses en concurrence pour l'espace dans le cache de données en mémoire de SQL Server.
D'autres fois, nous pouvons créer quelques index supplémentaires (peut-être filtré dans SQL Server 2008+) avec juste assez INCLUDE
colonnes pour satisfaire la grande majorité des requêtes critiques de la performance, sans trop compromettre la performance de modification de données, et sans utiliser trop d'espace disque supplémentaire. L'équilibrage des considérations concurrentes est ce qui rend l'indexage plus d'art que la science.
Vous demandez quel coût de 99% pour l'opérateur de recherche moyen dans le plan de requête. Le composant des coûts de la requête Optimizer produit un coût estimé pour cette opération de 99% du total estimé pour la requête. Le nombre lui-même (0,29) ne signifie pas beaucoup; Pour toutes les raisons pratiques, vous devez le considérer comme un numéro d'unité moins utilisé en interne par l'optimiseur lors de la comparaison de stratégies alternatives pour cette requête spécifique.
Le coût estimé ne prend aucun compte de votre matériel, de votre configuration, de vos besoins en matière d'applications ou de toute autre chose d'autre. Le modèle de coût utilisé par l'optimiseur comprend un nombre important d'heuristiques et de simplifier les hypothèses qui se produisent pour produire des plans raisonnables la plupart du temps, pour la plupart des requêtes, sur la plupart des querres. Cela ne veut pas dire qu'il y a -NON corrélation entre les opérateurs à prix élevé dans les plans et les performances; Le lien est plutôt beaucoup plus faible que celui attendu. Par tous, vérifiez d'abord les raisons des opérateurs de régimes de coûts élevés, mais ne traitez pas l'information comme une estimation très éventuellement imparfaite.
Je tiens également à mentionner quelques facteurs pouvant améliorer l'impact des recherches. Premièrement, j'ai mentionné dès le début que le pire des cas implique I/O physique à ligne. Cela sera évidemment évité si les pages de données (index en cluster ou tas) nécessaires pour satisfaire les recherches sont déjà en mémoire (cache de données). Lorsque tel est le cas, la différence de temps d'exécution entre un plan avec une recherche par rapport à un indice de couverture peut bien être incommensurable. Même lorsque des E/S physiques sont nécessaires, si le nombre de lectures est petit, vous ne vous souciez toujours pas. (Quelle est la probabilité que les pages de données pour une table doivent figurer dans le cache de données dépendent de nombreux facteurs et seront spécifiques à votre matériel et à votre situation).
Là où plus qu'un peu d'E/S physique est nécessaire, l'impact des recherches peut encore être réduit par des optimisations présentes dans le plan de requête. Si SQL Server s'attend à ce que le nombre de recherches soit significatif, il peut choisir de trier explicitement les lignes entrant dans les boucles imbriquées Joindre la recherche de la recherche dans l'ordre des clés non groupées. Cette réorganisation favorise la lecture séquentielle de l'indice non clustered, qui peut être très plus rapide que l'E/S aléatoire sur votre matériel.
Avec ou sans trier explicite, les boucles imbriquées rejoignent la conduite de la recherche peuvent avoir les attributs WithOrderedPrefetch
ou WithUnorderedPrefetch
attributs présents. Dans les deux cas, le moteur d'exécution de la requête 'regarde à l'avenir' dans le flux de clé d'index entraînant la recherche et les problèmes lecture-avance Lit. L'idée est de délivrer asynchrone lire les demandes de lecture au système d'E/S pour les pages de données qui seront bientôt nécessaires, de sorte que la recherche a besoin d'une page de données, elle est déjà présente en mémoire.
Dans des conditions idéales (faibles fragmentation, bon plan de requête, système d'E/S hautes performances) Le mécanisme de lecture à l'avance pourrait bien être suffisamment rapide pour empêcher même de grandes plans de requête parallèles d'attendre toujours des E/S. Cela est particulièrement vrai dans l'édition d'Enterprise, qui peut émettre de très grandes demandes d'E/S Simple (jusqu'à 2 Mo par demande si la mémoire sert). D'autre part, sous des conditions moins importantes que d'idéales (plus normales!), Votre requête peut souffrir horriblement à mesure que cela attend sur des files d'attente d'E/S longues, ou ne parvient pas à entraîner suffisamment le système d'E/S. La pire performance des recherches clines peut être très médiocre.
En résumé, vous voulez généralement Voulez-vous éviter les recherches où il est logique de le faire. Pour de petites questions (qui vont rester petits), vous pouvez décider que les frais généraux d'index supplémentaires (espace et maintenance) ne sont pas justifiés, donnés au poids dû aux besoins plus larges du système et de ses utilisateurs.
En fin de compte, cela fait partie de l'art et de la science qui est le développement et l'administration de la base de données.