2010-07-10 6 views
1

Je regarde certaines fonctionnalités qui me permettront de partitionner des tables horizontalement, c'est-à-dire que le contexte dans lequel je me réfère à une table n'est qu'un sous-ensemble de l'ensemble des enregistrements d'une table. Cela pourrait être un scénario typique dans un modèle SaaS puisque les données d'un compte ne sont pas significatives pour un autre. Disons qu'il y a un identifiant de compte attaché à une table de transaction. Une fois que je me connecte à mon compte, l'identifiant du compte est défini. Les recherches se terminent toujours par AND accountid = 25.. Cependant, le plan d'exécution de la requête considère les millions d'enregistrements de la table liés à plusieurs comptes, ce qui affecte les performances de l'exécution de la requête. Est-il possible de dire que les opérations au niveau de la table du plan d'exécution doivent être effectuées uniquement dans la partition définie par accountid = 25 de sorte qu'un balayage de table est seulement les 100 enregistrements qui se qualifient sous accountid = 25.Optimisation de requête SQL Server Select

+0

Quel système de base de données utilisez-vous? Oracle, SQL Server, mySql, autre chose? – Oded

+1

@krock - Je me demandais comment vous avez déterminé que c'est SQL Server et pas un autre SGBDR? – Oded

+0

@Oded - À partir du titre je supposerais regarder l'histoire. –

Répondre

0

Pour Microsoft SQL Server, un regard sur CREATE PARTITION FUNCTIONhere

5

Il me semble que vous êtes moins dans le besoin de partage et plus besoin d'indices sur votre colonne accountid. Si vos requêtes qui incluent accountid analysent des tables entières, il est probable que vous manquiez d'index pertinents.

+1

D'accord, ceci est un problème d'indexation pas un partitionnement – gbn

3

Vous devez modifier votre table (s) d'avoir account_id comme première colonne dans l'index en cluster. Ajouter simplement un index non clusterisé sur account_id ne suffira pas, car les requêtes atteindront le index tipping point et ignoreront l'index. En outre, le partitionnement de la table sur account_id n'aidera pas tout seul. Le partitionnement est une solution de stockage et d'ETL, pas une solution de performance.

Donc, si vous avez actuellement un nom de table Transactions actuellement définies comme:

create table Transactions (
    TransactionId int not null primary key, 
    TransactionDate datetime not null, 
    Amount money not null, 
    AccountId int not null, 
    constraint FKAccountId 
    foreign key AccountId 
    references Accounts(AccountId)); 

Il devrait être modifiée de sorte que la clé primaire ne soit pas en cluster et l'indice de regroupement est (AccountId, TransactionId):

create table Transactions (
    TransactionId int not null , 
    TransactionDate datetime not null, 
    Amount money not null, 
    AccountId int not null, 
    constraint FKAccountId 
    foreign key AccountId 
    references Accounts(AccountId), 
    constraint PKTransactionId 
    primary key nonclustered (TransactionId)); 
create clustered index cdxTransactions 
    on Transactions (AccountId, TransactionId); 

Ceci est juste un exemple, je ne peux pas prétendre que je peux modeler sur le bleu là-bas votre modèle de données approprié. Mais l'idée est la suivante: si votre modèle d'accès répandu est toujours filtré par une colonne, cette colonne doit généralement faire partie de l'index clusterisé dans une position la plus à gauche,. Seulement de cette façon, la requête peut effectuer une analyse de plage qui limite toutes les données lues uniquement au compte concerné.

0

Vous pouvez passer en revue quelques petites choses: -
1. index Filtré - nouvelle fonctionnalité
2. partitionner votre table en accountId/clientId et placer chaque partition sur filegroup séparée et à son tour fournir plus de broches (c.-à- disques) à des comptes plus importants.
ps: notez qu'il existe une limite maximale sur le nombre de partitions que vous pouvez avoir pour une table, c'est-à-dire 1000.