SQL Server选择查询优化

时间:2010-07-10 06:21:31

标签: sql sql-server optimization

我正在研究一些能够让我水平分区表的功能,即我引用表的上下文只是表中整个记录集的子集。这可能是SaaS模型中的典型情况,因为一个帐户的数据对另一个帐户不重要。让我们说,有一个帐户ID附加到事务表。登录帐户后,即会设置帐户ID。搜索始终以AND accountid = 25.结束但是,查询执行计划将考虑表中与多个帐户相关的数百万条记录,从而影响查询执行的性能。是否有一些方法可以说执行计划的表级操作只需要在accountid = 25定义的分区内执行,这样表扫描只能是accountid = 25下符合条件的100条记录。

4 个答案:

答案 0 :(得分:5)

在我看来,您不再需要分区,而且需要在accountid列上更需要索引。如果包含accountid的查询正在扫描整个表格,那么您很可能错过了相关索引。

答案 1 :(得分:3)

您需要修改表格,将account_id作为群集索引中的第一个列。仅在account_id上添加非聚集索引是不够的,因为查询将到达index tipping point并忽略索引。此外,在account_id上对表进行分区本身也无济于事。分区是一种存储和ETL解决方案,而不是性能解决方案。

因此,如果您当前有一个表名称Transactions,当前定义为:

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));

必须进行更改,以便主键不会群集并且群集索引处于打开状态(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);

这只是一个例子,我不能声称我可以用蓝色模型建立正确的数据模型。但我们的想法是,如果您的流行访问模式始终按列过滤,则该列通常需要成为最左侧位置中的聚簇索引的一部分。只有这样,查询才能进行范围扫描,将所有数据限制为仅读取到相关帐户。

答案 2 :(得分:0)

对于Microsoft SQL Server,请查看CREATE PARTITION FUNCTION here

答案 3 :(得分:0)

您可以查看以下几点: - 1. 过滤索引 - 新功能
2. 通过accountId / clientId 对您的表进行分区,并将每个分区放在单独的文件组中,然后为更大的帐户提供更多的磁盘轴(即磁盘)。
ps:请注意,您可以为表格分配多少个分区,例如1000个。