2008-09-23 7 views
15

Supposons que vous avez une table massive avec trois colonnes comme indiqué ci-dessous:SQL Server - Tables partitionnées et index clusterisé?

[id] INT NOT NULL, 

[date] SMALLDATETIME NOT NULL, 

[sales] FLOAT NULL 

Supposons également que vous êtes limité à un disque physique et un groupe de fichiers (primaire). Vous vous attendez à ce que cette table contienne des ventes pour 10 000 000 ID +, à travers 100 des dates (enregistrements facilement 1B +). Comme avec de nombreux scénarios d'entreposage de données, les données vont généralement croître séquentiellement par date (à chaque fois que vous effectuez une charge de données, vous insérerez de nouvelles dates, et peut-être mettre à jour certaines dates de données plus récentes). À des fins analytiques, les données seront souvent interrogées et agrégées pour un ensemble aléatoire de ~ 10 000 identifiants qui seront spécifiés via une jointure avec une autre table. Souvent, ces requêtes ne spécifient pas les plages de dates, ou spécifient des plages de dates très larges, ce qui m'amène à ma question: Quelle est la meilleure façon d'indexer/partitionner cette table?

J'ai pensé pendant un certain temps, mais je suis coincé avec des solutions contradictoires:

Option 1: Comme les données seront chargées séquentiellement par date, définissez l'index cluster (et clé primaire) comme [ date], [id]. Créez également une fonction/un système de partitionnement "fenêtre glissante" à la date permettant un déplacement rapide des nouvelles données dans/hors de la table. Potentiellement créer un index non-cluster sur ID pour aider à l'interrogation.

Résultat attendu # 1: Cette configuration sera très rapide pour le chargement de données, mais sous-optimale en matière de lecture analytique comme, dans le pire des cas (pas de limitation de dates, de chance avec l'ensemble des id interrogé), 100% des pages de données peuvent être lues. Comme les données ne seront interrogées que pour un petit sous-ensemble d'ID à la fois, définissez l'index clusterisé (et la clé primaire) comme [id], [date]. Ne vous embêtez pas à créer une table partitionnée.

Résultat attendu n ° 2: Atteinte d'une énorme performance attendue lors du chargement de données car nous ne pouvons plus limiter rapidement par date. Bénéfice de performance énorme attendu en ce qui concerne mes requêtes analytiques, car il minimisera le nombre de pages de données lues.

Option 3: En cluster (et clé primaire) comme suit: [id], [date]; fonction/schéma de partition "fenêtre glissante" à la date.

Résultat attendu n ° 3: Je ne sais pas à quoi m'attendre. Étant donné que la première colonne de l'index clusterisé est [id] et donc (d'après ce que je comprends) les données sont classées par ID, je m'attendrais à de bonnes performances de mes requêtes analytiques. Cependant, les données sont partitionnées par date, ce qui est contraire à la définition de l'index clusterisé (mais toujours aligné car la date fait partie de l'index). Je n'ai pas trouvé beaucoup de documentation qui traite de ce scénario et des avantages de performance que cela peut apporter, ce qui m'amène à ma dernière question bonus:

Si je crée une table sur un groupe de fichiers un disque, avec un index clusterisé sur une colonne, y at-il un avantage (en plus de la commutation de partition lors du chargement des données) qui provient de la définition d'une partition sur la même colonne?

Répondre

0

Si vous utilisez les partitions dans les instructions select, vous gagnez de la vitesse.

Si vous ne l'utilisez pas, en utilisant uniquement des sélections "standard", vous n'avez aucun avantage.

Sur votre problème d'origine: Je vous recommanderais l'option # 1 avec l'index non-cluster sur l'ID inclus.

3

Un index clusterisé offre des avantages en termes de performances pour les requêtes lors de la localisation des E/S. La date est une stratégie de partitionnement traditionnelle car de nombreuses requêtes D/W examinent les mouvements par date. Une règle empirique pour une table partitionnée suggère que les partitions doivent avoir une taille d'environ 10 m.

Il serait quelque peu inhabituel de constater un gain de performance considérable d'un index clusterisé sur une charge de travail analytique diversifiée. L'optimiseur de requête utilisera une technique appelée 'Index Intersection' pour sélectionner des lignes sans même atteindre la table de faits. Voir Here pour un post que j'ai fait sur une autre question qui explique cela plus en profondeur avec quelques liens. Un index clusterisé peut participer ou non à l'intersection de l'index, de sorte que vous pouvez constater qu'il vous gagne relativement peu sur une charge de travail de requête générale.

Vous pouvez trouver des circonstances de chargement où les index clusterisés vous procurent un certain gain, en particulier si vous avez des calculs dérivés (tels que Earned Premium) calculés dans le processus ETL. Dans ce cas, vous pouvez obtenir des avantages. Si vous avez une requête spécifique dont vous savez qu'elle sera exécutée tout le temps, il peut être judicieux d'utiliser des index clusterisés pour cela. Les options # 2 et # 3 ne vont que vous être très bénéfiques si vous pensez que ce type de requête représente l'écrasante majorité du travail effectué par l'application. Pour un système flexible, une partition de plage de dates simple avec un index sur l'ID (et une date si les partitions contiennent une plage vous donneront probablement une performance aussi bonne que n'importe quelle autre. . circonstances Vous pouvez également obtenir un certain kilométrage de construire un cube sur les données et veiller à ce que les agrégations sont correctement configurées pour cette requête

0

je ferais ce qui suit:.

  • index non cluster sur [ Id]
  • Index clusterisé le [Date]
  • Convertir le [ventes] DataType numériques au lieu de flotter
+0

Votre dernier point est intéressant. Quel type de bénéfice en termes de performances attendez-vous de la conversion en numérique de float? –

+1

Vous pouvez être plus précis sur les données que vous stockez et le type de données numérique est un nombre exact où un flottant est un nombre approximatif. – GateKiller

7

Ce tableau est awesomely étroite. Si la table réelle sera aussi étroite, vous devriez être heureux d'avoir des scans de table au lieu de l'index-> ​​recherches.

je ferais ceci:

CREATE TABLE Narrow 
(
    [id] INT NOT NULL, 
    [date] SMALLDATETIME NOT NULL, 
    [sales] FLOAT NULL, 
    PRIMARY KEY(id, date) --EDIT, just noticed your id is not unique. 
) 

CREATE INDEX CoveringNarrow ON Narrow(date, id, sales) 

Cette poignées requêtes ponctuelles avec cherche et les requêtes de grande portée avec des analyses limitées par rapport aux critères de date et les critères d'identification. Il n'y a pas de recherche par enregistrement à partir de l'index. Oui, j'ai doublé le temps d'écriture (et l'espace utilisé) mais ça va, imo.


S'il y a un certain besoin d'un morceau spécifique de données (et ce besoin est démontré par le profilage !!), je créerais une vue en clusters cette section de ciblage du tableau.

CREATE VIEW Narrow200801 
AS 
SELECT * FROM Narrow WHERE '2008-01-01' <= [date] AND [date] < '2008-02-01' 
--There is some command that I don't have at my finger tips to make this a clustered view. 

vues en cluster peuvent être utilisés dans les requêtes par nom, ou l'optimiseur choisiront d'utiliser les vues groupées lorsque la clause et où sont appropriées. Par exemple, cette requête utilisera la vue en cluster.Notez que la table de base est référencée dans la requête.

SELECT SUM(sales) FROM Narrow WHERE '2008-01-01' <= [date] AND [date] < '2008-02-01' 

Comme index vous permet de créer des colonnes spécifiques facilement accessible ... vue en cluster vous permet de faire des lignes spécifiques facilement accessibles.

+0

Merci pour la réponse. Je ne suis pas familier avec les vues groupées. Aucun résultat clair n'est revenu lorsque je l'ai googlé. Pouvez-vous me fournir/me diriger vers d'autres informations? –

+0

Bien sûr, voici msdn http://msdn.microsoft.com/en-us/library/aa933148.aspx La grande exigence est le schemabinding (qui bloque les modifications apportées aux structures dépendantes alors que cette structure existe). –

0

Partitionnez la table par date. Plusieurs partitions horizontales seront plus performantes qu'une grande table avec autant de lignes.

0

L'index cluster sur la colonne de date n'est pas bon si vous avez des insertions qui seront insérées plus rapidement que la résolution datetime de 3,33 ms. Si vous le faites vous obtiendrez 2 clés avec la même valeur et votre index devra obtenir un autre uniquificateur interne qui augmentera sa taille.

J'irais aveC# 2 de vos options.

Questions connexes