Pourquoi SQL Server ne fait-il pas d'histogrammes de statistiques de colonnes composées?

10

SQL Server a une chose appelée "statistiques multi-colonnes", mais ce n'est pas ce que l'on pense que cela signifierait.

Jetons un coup d'œil à l'exemple de tableau suivant:

CREATE TABLE BadStatistics 
(
    IsArchived BIT NOT NULL,
    Id INT NOT NULL IDENTITY PRIMARY KEY,
    Mystery VARCHAR(200) NOT NULL
);

CREATE NONCLUSTERED INDEX BadIndex 
    ON BadStatistics (IsArchived, Mystery);

Avec cela, deux statistiques sont en cours de création sur les deux index que nous avons:

Statistiques pour BadIndex:

+--------------+----------------+-------------------------+
| All density  | Average Length | Columns                 |
+--------------+----------------+-------------------------+
| 0.5          | 1              | IsArchived              |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 37             | IsArchived, Mystery     |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 41             | IsArchived, Mystery, Id |
+--------------+----------------+-------------------------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0            | 0          | 24398   | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 216602  | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

Statistiques pour l'index clusterisé:

+--------------+----------------+---------+
| All density  | Average Length | Columns |
+--------------+----------------+---------+
| 4.149378E-06 | 4              | Id      |
+--------------+----------------+---------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 240999       | 240997     | 1       | 240997              | 1              |
+--------------+------------+---------+---------------------+----------------+
| 241000       | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

(J'ai rempli le tableau avec des échantillons de données aléatoires où environ un dixième des lignes ne sont pas archivées. J'ai ensuite exécuté une mise à jour complète des statistiques d'analyse.)

Pourquoi l'histogramme des statistiques à deux colonnes n'utilise-t-il qu'une seule colonne? Je sais que de nombreuses personnes ont écrit au sujet de ce qu'il fait , mais quelle est la raison d'être ? Dans ce cas, cela rend l'histogramme entier beaucoup moins utile, car la première colonne n'a que deux valeurs. Pourquoi les statistiques seraient-elles arbitrairement restreintes comme ça?

Veuillez noter que cette question ne fait pas référence aux histogrammes multidimensionnels, qui sont une bête entièrement différente. Il s'agit d'histogrammes unidimensionnels, la dimension unique étant les tuples contenant les multiples colonnes respectives.

John
la source

Réponses:

8

Contexte

Le modèle SQL Server actuel utilise uniquement des histogrammes à colonne unique et des informations de densité à plusieurs colonnes. Des histogrammes à colonne unique sont utilisés pour estimer la sélectivité pour des prédicats appropriés, par exemple a = 1ou b > 50. Une requête avec plusieurs prédicats combine simplement les sélectivités individuelles (avec des hypothèses) pour produire une sélectivité globale estimée.

Pour un exemple, voir mon article Estimation de la cardinalité: combinaison des statistiques de densité

La densité multi-colonnes informe davantage le modèle en fournissant des informations de corrélation faibles pour les prédicats d'égalité multiples et en regroupant les cardinalités pour les agrégations.

Les statistiques associées aux index sont un complément opportuniste à ce modèle: le moteur peut aussi bien collecter (normalement l'analyse complète) des statistiques pendant qu'il construit un index. SQL Server crée automatiquement un histogramme de colonne de tête et des informations de densité pour les autres clés.

Les histogrammes des colonnes non en tête d'un index peuvent être construits à la demande automatiquement par le processeur de requêtes, ou à l'avance en utilisant sp_createstatsl' @indexonlyoption (entre autres).

Histogrammes multi-colonnes

Les hypothèses formulées lors de la combinaison de statistiques sur une seule colonne (comme ci-dessus) peuvent ou non suffisamment bien modéliser la réalité des données. Dans de nombreux cas, les options disponibles (interruption exponentielle, indépendance, sélectivité minimale) produisent une estimation «suffisamment bonne».

Nous avons également filtré les statistiques (et les index) comme solution naturelle aux index des colonnes de tête à faible cardinalité comme dans l'exemple de question. Les pousser à l'extrême logique nous rapproche des statistiques multidimensionnelles sur lesquelles la question ne porte pas.

Lorsque les options de modélisation disponibles ne peuvent pas fournir une estimation appropriée, un histogramme statistique à plusieurs colonnes pourrait en effet donner une meilleure estimation de la sélectivité pour les prédicats d'indice appropriés, dans certains cas. Il y a quelques difficultés à combiner différents types de données dans différentes colonnes, mais rien d'insurmontable.

Nous aurions également besoin d'un histogramme pour chaque niveau des clés d'index (pour de meilleurs résultats); donc pour un index sur (a, b, c)cela signifierait des histogrammes sur (a, b)et (a, b, c)en plus de l'histogramme à colonne unique actuel sur (a)seul.

Le mécanisme utilisé pour détecter les statistiques périmées devrait également être modifié pour maintenir les histogrammes multi-colonnes affectés. Ces histogrammes finiraient probablement par être reconstruits plus souvent que les statistiques à colonne unique, simplement parce que des modifications apportées à davantage de colonnes les affectent.

Tout cela ajoute de la taille, de la complexité et des frais de maintenance.

Les statistiques multi-colonnes peuvent être simulées (dans une mesure limitée) en utilisant une statistique créée sur une colonne calculée soigneusement et référençant plusieurs colonnes. La requête devrait inclure un prédicat sur la colonne calculée (ou une correspondance textuelle exacte pour la formule sous-jacente) pour tirer parti de cette statistique. Il n'y a probablement que des situations très limitées où cette approche est pratique. Néanmoins, il présente certains des mêmes problèmes de mise en œuvre que les histogrammes automatiques à plusieurs colonnes.

En fin de compte, les concepteurs eux-mêmes seraient les seuls à pouvoir dire avec certitude pourquoi SQL Server ne prend pas en charge les statistiques multi-colonnes. Si vous pensez que vous pouvez plaider en faveur d'une amélioration du produit dans ce domaine avec une large applicabilité, vous pouvez le suggérer sur Connect ou via votre canal de support normal.

note de bas de page

Dans ce cas, cela rend l'histogramme entier beaucoup moins utile, car la première colonne n'a que deux valeurs

L'histogramme fournit toujours des informations utiles sur la distribution des valeurs dans la première colonne: lorsque les statistiques ont été créées, il y avait 24 398 lignes où IsArchivedétait faux et 216 602 lignes où était vrai .

De plus, l'objet statistique nous indique qu'il y a (1 / 0,5) = 2 valeurs distinctes pour IsArchived, (1 / 4,149378E-06) ~ = 241000 valeurs distinctes pour (IsArchived, Mystery)avec une taille de ligne moyenne de 37 octets, et il y a la même fréquence pour (IsArchived, Mystery, Id)avec 4 octets supplémentaires par ligne.

Ce sont toutes de bonnes informations à usage général, qui peuvent être combinées avec des informations statistiques sur d'autres colonnes pour produire une estimation de la sélectivité dans les requêtes avec plusieurs prédicats (comme mentionné).

Paul White 9
la source