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:
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?
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.
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 ;-)
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.
Non, cela n'aura probablement pas d'impact négatif sur les requêtes SELECT
, mais
INSERT
.WHERE
n'utilisent toujours pas d'indices, principalement les plus complexes.