les statistiques sont à jour, mais l'estimation est incorrecte


12

Lorsque dbcc show_statistics ('Reports_Documents', PK_Reports_Documents)j'obtiens, j'obtiens le résultat suivant pour le rapport ID 18698:

entrez la description de l'image ici

Pour cette requête:

SELECT * 
FROM Reports_Documents 
WHERE ReportID = 18698 option (recompile)

J'obtiens un plan de requête qui effectue une recherche d'index cluster PK_Reports_Documentscomme prévu.

Mais ce qui me déroute, c'est la valeur incorrecte du nombre estimé de lignes:

entrez la description de l'image ici

Selon ceci :

Lorsque l'exemple de valeur de clause WHERE de requête est égal à une valeur d'histogramme RANGE_HI_KEY, SQL Server utilise la colonne EQ_ROWS dans l'histogramme pour déterminer le nombre de lignes égales à

C'est aussi ainsi que je m'attendrais à ce que ce soit, mais cela ne semble pas être le cas dans la vraie vie. J'ai également essayé d'autres RANGE_HI_KEYvaleurs présentes dans l'histogramme fourni par show_statisticset vécu les mêmes. Ce problème dans mon cas semble entraîner certaines requêtes à utiliser des plans d'exécution très peu optimaux entraînant un temps d'exécution de quelques minutes alors que je peux le faire fonctionner en 1 seconde avec un indice de requête.

Dans l'ensemble: quelqu'un peut-il m'expliquer pourquoi EQ_ROWSl'histogramme n'est pas utilisé pour le nombre estimé de lignes et d'où vient l'estimation incorrecte?

Un peu plus d'informations (peut-être utiles):

  • La création automatique de statistiques est activée et toutes les statistiques sont à jour.
  • La table interrogée compte environ 80 millions de lignes.
  • PK_Reports_Documentsest une combinaison PK composée de ReportID INTetDocumentID CHAR(8)

La requête semble charger un total de 5 objets statistiques différents, qui contiennent tous ReportID+ quelques autres colonnes de la table. Ils ont tous été mis à jour récemment. RANGE_HI_KEYdans le tableau ci-dessous est la valeur de la colonne supérieure la plus élevée de l'histogramme.

+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
|                                  name                                   | stats_id | auto_created | user_created | Leading column Type | RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS  | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
| PK_Reports_Documents                                                    |        1 |            0 |            0 | Stationary          |        18722 | 0          | 2228,526 |                   0 | 1              |
| _dta_index_Reports_Documents_42_1629248859__K1_K63_K14_K13_K22_K23_72_6 |       62 |            0 |            0 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_1_59                                             |       76 |            0 |            1 | Stationary          |        18686 | 50,56393   | 1        |                   0 | 13397,04       |
| _dta_stat_1629248859_1_22_14_18_12_6                                    |       95 |            0 |            1 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_7_14_4_23_62                                     |       96 |            0 |            1 | Stationary          |        18698 | 56,63327   | 21641,5  |                   0 | 14526,44       |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+

sp_updatestats doit être exécuté tous les soirs pour mettre à jour les statistiques.

Réponses:


10

Il existe une solution simple à cela:

Supprimez toutes les _dta_...statistiques et cessez d'appliquer aveuglément les recommandations DTA.

Plus d'information

Le problème particulier était qu'il y avait plusieurs ensembles de statistiques pour la colonne en question. Les dtastatistiques supplémentaires ont été créées en échantillonnant les données (le comportement par défaut pour les statistiques non associées à un index).

Comme c'est souvent le cas avec les statistiques échantillonnées, les histogrammes résultants ne couvraient pas la gamme complète des données sous-jacentes. La requête dans la question s'est avérée choisir une valeur qui était en dehors de l'histogramme, résultant en une estimation sur 1 ligne.

Le comportement exact de l'optimiseur de requêtes lorsque plusieurs ensembles de statistiques existent pour la même colonne n'est pas entièrement documenté. Il a tendance à préférer les statistiques de «balayage complet» aux échantillons, mais il préfère également les statistiques plus récemment mises à jour aux anciennes.


Cela fonctionne effectivement. Je n'ai cependant pas créé les _dta_statistiques, elles étaient là depuis que j'ai eu mon premier aperçu sur la DB. Je ne savais pas que l'utilisation des recommandations pouvait avoir de tels effets négatifs ...
user1151923
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.