Je suis en train de concevoir un tableau d'articles qui contiendra (potentiellement) des dizaines de millions d'enregistrements. Certains éléments ne seront pas disponibles jusqu'à ce qu'ils soient «approuvés» par l'administrateur. Par «utiliser», je veux dire que ces éléments ne seront référencés dans aucun autre tableau tant qu'ils ne seront pas «approuvés». Jusqu'à 50% des articles peuvent être «non approuvés» à tout moment. Les enregistrements peuvent devenir "approuvés", mais pas l'inverse.
Je considère deux options de conception:
- un peu de drapeau
- un tableau séparé des articles "non approuvés" - lorsque l'article est approuvé, il est déplacé vers le tableau "normal" (le renouvellement de l'ID de l'article n'est pas un problème)
Je pense que la deuxième option est bien meilleure. L'indicateur de bit ne prend qu'un octet par ligne, donc ce n'est pas un problème. Mais si nous avons un million d'enregistrements approuvés et un million d'enregistrements non approuvés dans le même tableau - le temps d'analyse augmente pour les opérations avec des enregistrements approuvés.
La question est: devrais-je considérer la première option (indicateur de bit) à la place? At-il des avantages dans la situation décrite?
WHERE status='A'
et une requête aWHERE status = 'A' AND (... other columns and parameters here...)
, l'indice pourrait encore être utilisé.Réponses:
Vous pouvez l'avoir dans les deux sens avec des vues partitionnées .
Vous créez une table sous-jacente pour chaque statut, imposée par des contraintes, avec des valeurs mutuellement exclusives. Puis une vue qui UNIONs ensemble les tables sous-jacentes. La vue ou chaque table de base peut être référencée explicitement. Si le statut d'une ligne est mis à jour via la vue, le SGBD la supprimera d'une table de base et l'insérera dans celle correspondant au nouveau statut. Chaque table de base peut être indexée indépendamment selon son modèle d'utilisation. L'optimiseur résoudra les références d'index à une seule table de base correspondante si c'est possible.
Les avantages sont
a) des indices moins profonds. Faites le calcul sur le fan-out d'index, cependant. À cette échelle et réparti entre vos valeurs de statut, il est possible que les index aient la même profondeur sur les tables fractionnées qu'ils le seraient sur la table combinée.
b) aucun code d'application ne doit changer. Les données continuent d'apparaître comme un tout continu.
c) de nouvelles valeurs de statut futures peuvent être incluses en ajoutant une nouvelle table de base, avec contrainte, et en recréant la vue.
Le coût est tout ce mouvement de données; deux pages et les index associés sont écrits pour chaque mise à jour de statut. Beaucoup d'E / S à gérer. Cette quantité de mouvements entraînera également une fragmentation.
la source
Ce n'est en fait pas tant que ça, étant donné ce que SQL Server peut gérer efficacement. Bien sûr, je me souviens d'un de mes emplois précédents où l'une des plus grandes tables (un système à instance unique) avait 2 millions de lignes et c'était le plus que j'avais jamais traité. Ensuite, le travail suivant avait 17 instances de production avec certaines tables ayant des centaines de millions de lignes, et qui ont toutes été regroupées dans un entrepôt de données avec plusieurs tables de faits ayant plus d'un milliard de lignes. Ne vous méprenez pas, je ne me moque pas de dizaines de millions de lignes, je souligne simplement qu'avec un bon modèle de données et une indexation (et une maintenance d'index) appropriées, SQL Server peut gérer beaucoup .
Hmm. Cela ne semble pas juste. Le taux «d'approbation» des entrées sera la moitié du taux d'obtention de nouvelles entrées? Pour chaque 2 nouvelles entrées, une seule sera "approuvée"? Dans votre exemple de 2 millions de lignes, et 1 million chacune pour "approuvé" et "non approuvé", quelques années plus tard avec encore 10 millions d'entrées, vous vous attendez à 6 millions chacune pour "approuvé" et "non approuvé"? Ou est-ce que le 1 million "non approuvé" restera quelque peu constant, de sorte qu'avec 10 millions de nouvelles entrées, il y aura 11 millions "approuvé" et toujours 1 million "non approuvé"?
C'est vrai aujourd'hui , mais les choses changent avec le temps et il y a donc toujours la possibilité que l'entreprise décide d'autoriser "non approuvé", ou peut-être un autre statut, comme "archivé", etc.
Alors, regardons les choix:
Drapeau (ou peut-être même
TINYINT
"statut")TINYINT
colonneDeux tableaux distincts (un pour «approuvé», un pour «non approuvé»)
IDENTITY
colonne, et la table approuvée a une colonne ID qui n'est pas uneIDENTITY
(car elle n'est pas nécessaire à cet endroit). Par conséquent, les valeurs d'ID restent cohérentes lorsque l'enregistrement se déplace entre les tables.Personnellement, je me pencherais vers la table unique avec
StatusID
colonne pour commencer. L'utilisation de deux tables semble être une optimisation trop compliquée et prématurée. Ce type d'optimisation peut être discuté si / lorsque le nombre d'enregistrements est de plusieurs centaines de millions et que l' indexation n'apporte aucun gain de performances.la source