2010-01-08 3 views
3

Supposons que vous ayez une table avec une cote à changement lent de type 2.Comment indexer une table avec une dimension à changement lent de type 2 pour des performances optimales

Exprimons ce tableau comme suit, avec les colonnes suivantes:

* [Key] 
* [Value1] 
* ... 
* [ValueN] 
* [StartDate] 
* [ExpiryDate] 

Dans cet exemple, supposons que [StartDate] est effectivement la date à laquelle les valeurs d'une donnée [Key] devenir connu le système. Donc, notre clé primaire serait composée à la fois de [StartDate] et de [Key].

Lorsqu'un nouvel ensemble de valeurs arrive pour une [Clé] donnée, nous affectons [ExpiryDate] à une valeur de substitution élevée prédéfinie telle que '12/31/9999 '. Nous définissons ensuite les enregistrements "les plus récents" pour cette [Clé] afin d'avoir un [ExpiryDate] égal au [StartDate] de la nouvelle valeur. Une mise à jour simple basée sur une jointure.


Donc, si nous voulions toujours obtenir les plus récents enregistrements pour une donnée [Key], nous savons que nous pourrions créer un index cluster qui est:

* [ExpiryDate] ASC 
* [Key] ASC 

Bien que le keyspace peut être très large (disons, un million de clés), nous pouvons minimiser le nombre de pages entre les lectures en les ordonnant d'abord par [ExpiryDate]. Et puisque nous savons que l'enregistrement le plus récent pour une clé donnée aura toujours un [ExpiryDate] de '12/31/9999 ', nous pouvons l'utiliser à notre avantage. Cependant, que se passe-t-il si nous voulons obtenir un instantané ponctuel de toutes les [clés] à un moment donné? Théoriquement, l'ensemble de l'espace de clé n'est pas mis à jour en même temps. Par conséquent, pour un instant donné, la fenêtre entre [StartDate] et [ExpiryDate] est variable, donc la commande par [StartDate] ou [ExpiryDate] ne produira jamais un résultat dans lequel tous les enregistrements que vous recherchez sont contigu. Accordé, vous pouvez immédiatement jeter tous les enregistrements dans lesquels le [StartDate] est supérieur à votre point-dans-temps défini.


En substance, dans un SGBDR typique, quelle stratégie d'indexation permet la meilleure façon de réduire le nombre de lectures pour récupérer les valeurs de toutes les clés d'un point à temps donné? Je me rends compte que je peux au moins maximiser IO en partitionnant la table par [Key], mais ce n'est certainement pas idéal.

Ou bien existe-t-il un autre type de changement lent qui résout ce problème d'une manière plus performante?

+0

Utilisez-vous Analysis Services? –

Répondre

1

Lazy DBA

Vous parlez de ramener toutes les valeurs dans votre table de dimension? Si oui, pourquoi ne pas ajouter un index non cluster avec une couverture supplémentaire de sorte que vous extrayez uniquement des valeurs de l'index lui-même plutôt que de la table? De cette façon, vous numérisez un arbre B avec des valeurs "couvertes" jointes, par opposition à potentiellement effectuer un balayage de table? Je ne peux pas garantir la performance relative, mais cela vaut la peine de tester le scénario sur lequel vous travaillez.

Vive

Ozziemedes http://ozziemedes.blogspot.com/

0

Si cela est vraiment une table "dimension changeant lentement", je considère comme un indice de columnstore en cluster. Je sais que ce n'était pas disponible quand vous avez posé la question, mais de toute façon.vous trouverez une grande documentation ici: "https://msdn.microsoft.com/en-us/library/gg492088.aspx" et ici "http://www.nikoport.com/2013/07/05/clustered-columnstore-indexes-part-1-intro/". Maintenant, si vous voulez vous en tenir aux index rowstore, si vous insérez les données dans une table de manière séquentielle, ce que j'ai fait dans le passé était de tirer parti d'un champ d'identité. vos requêtes seraient quelque chose comme:

declare @id; 
    select @id = min(ID) from table where date = '12/31/9999'; 
    select fields from table where key = 112 and id > @id; 
Questions connexes