web-dev-qa-db-fra.com

Si une base de données n'a qu'un seul insert, est-il mauvais d'indexer toutes les combinaisons de colonnes possibles?

Je travaille sur un système de rapports qui nécessitera de grandes requêtes sélectionnées, mais est basé sur une base de données qui n'est remplie qu'une seule fois. Le système de gestion de base de données est Microsoft SQL Server 2017. Il existe probablement une meilleure façon de concevoir un système comme celui-ci, mais abordons cela théoriquement.

Théoriquement parlant:

  1. Si nous avons une très grande base de données (150M + lignes sur plusieurs tables)
  2. Et nous pouvons supposer que la base de données ne sera remplie qu'une seule fois.

L'indexation de chaque combinaison de colonnes possible pourrait-elle avoir un impact négatif sur les performances d'une requête sélectionnée?

24
Lopsided

Oui, cela influencera le temps de compilation du plan initial car l'optimiseur aura de nombreux chemins d'accès supplémentaires aux données à considérer.

Étant donné que vous utilisez SQL Server 2017, que vous chargez une fois et exécutez des rapports, pourquoi ne pas simplement utiliser un index de stockage de colonnes en cluster à la place?

Cela semble être la solution idéale à votre besoin d'indexer toutes les combinaisons de colonnes possibles.

Index Columnstore - Présentation

36
Erik Darling

Si vous avez N colonnes dans une table, chaque combinaison de colonnes possible est 2 ^ N-1 (en supprimant l'ensemble vide). Pour 10 colonnes, cela signifierait 1023 index, pour 20 colonnes, nous nous retrouvons avec un énorme 1048575 index. La plupart des index ne seront jamais utilisés mais devront être pris en compte par l'optimiseur. Il est possible que l'optimiseur choisisse un indice sous-optimal au lieu d'un meilleur. Je ne prendrais pas le chemin de la génération de toutes sortes d'index, au lieu d'essayer de déterminer quels index seraient réellement bénéfiques.

[~ # ~] modifier [~ # ~] nombre corrigé d'index possibles

Comme Jeff le souligne, c'est encore pire que 2 ^ N (power-set) car (3,2,1) est clairement différent de (1,2,3). Pour N colonnes, nous pouvons choisir la première position dans un index qui contient toutes les colonnes de N façons. Pour la deuxième position en N-1, etc. On se retrouve donc avec N! différents index de taille réelle. Aucun de ces index n'est subsumé par un autre index de cet ensemble. De plus, nous ne pouvons pas ajouter un autre index plus court afin qu'il ne soit couvert par aucun index complet. Le nombre d'index est donc N !. L'exemple pour 10 colonnes devient donc 10! = 3628800 index et pour 20 (drumroll) 2432902008176640000 index. C'est un nombre ridiculement élevé, si nous mettons un point pour chaque index un mm par pièce, il faudra un faisceau lumineux 94 jours pour passer tous les points. Dans l'ensemble, ne faites pas ;-)

27
Lennart

Non.

Il n'est pas pratique d'indexer "tout", mais vous pouvez indexer "la plupart" de celui-ci.

Voici le truc. Si une table a N colonnes, le nombre d'index possibles est N!. Disons qu'une table a 10 colonnes, alors vous n'avez pas seulement 10 index possibles, mais 10!. C'est ... 628 8 ... sur une seule table. Cela représente beaucoup d'espace disque, d'E/S disque, de cache et de temps de recherche.

Pourquoi? Quelques raisons:

  • Les index Lightwwight sont généralement mis en cache, ce qui les rend rapides à éclairer. Si vous en avez 3 millions, ils ne seront PAS mis en cache.

  • L'optimiseur SQL peut prendre beaucoup de temps pour décider lequel est préférable d'utiliser, en particulier lors de l'utilisation de jointures.

  • L'optimiseur SQL peut abandonner l'utilisation de l'algorithme complet et essayer un algorithme heuristique à la place. Cela peut être "moins qu'optimal". PostgreSQL, par exemple, propose différentes options pour les "requêtes de table inférieures à 8" et les "requêtes de table supérieures à 8".

  • Les index sont censés être plus légers que le tas. Si vous indexez tout, alors l'index devient aussi lourd que le tas ... quelque chose qui va à l'encontre de l'objectif de l'index.

7
The Impaler

Non, cela n'aura probablement pas d'impact négatif sur les requêtes SELECT, mais

  • Cela entraînera une utilisation élevée du disque.
  • Cela va énormément augmenter les coûts de INSERT.
  • La plupart de vos indices ne seront jamais utilisés.
  • De nombreuses expressions de condition WHERE n'utilisent toujours pas d'indices, principalement les plus complexes.
  • Le nombre d'indices requis augmentera de façon exponentielle avec le nombre de colonnes. C'est à dire. si vous avez, par exemple, 8 colonnes, vous avez besoin de 256 indices pour toutes les combinaisons possibles.