在多租户数据库中索引TenantID

4
我正在为一款应用创建多租户数据库。我选择了在每张表格中加入TenantID的方法,这种方法非常有效。现在我正处于性能调优阶段。
我的问题是,由于每个查询都会根据该列进行过滤,那么是否应该在每张表格中为每个TenantID建立索引以实现优化搜索?
期待您的建议。
谢谢。

1
这是否意味着tenantID不是所有表的外键,因此默认情况下成为外键索引? - xQbert
2个回答

5
尽管在索引时有许多需要考虑的因素,但根据我的经验,(唯一)聚集索引作为“tenantId + PK”效果很好。所有PK查询都可以在复合键上进行搜索。
这样做还有一个额外的好处,即将tenantID放在非聚集索引中,因为SQL Server使用聚集键作为从非聚集索引返回表的参考。
要注意页面分裂问题,因为插入几乎总是在页面中间,这种方法肯定优化了读取。请考虑使用70的填充因子并观察您的碎片情况,确保定期进行索引维护(无论如何都需要这样做)。
祝你好运。

你所说的“唯一聚类索引”,是指将每个表设置为具有由表当前主键和TenantID组成的复合主键吗?还是指在表上设置自定义聚类索引? - Matt
你可以选择任何一种方式。我假设你在表中有一个身份证或类似的主键。在这种情况下,租户ID从技术上讲不是主键的一部分,如果你已经设置了外键,可能很难创建一个组合键。上一次我走过类似的路线时,我创建了一个关于tenantid和身份证列的唯一聚集索引以及身份证列的非聚集主键。你目前的表结构是什么? - Code Magician
2
我同意,在所有聚集索引键中,tenantId 应该是最左边的列,并且所有谓词和连接都应该包括 tenantId - Remus Rusanu
目前它只有一个主键,而tenantID只是另一个非空列。例如EmployeeTable = EmployeeID PK,TenantID...当前没有设置FK键。我认为在PK列上设置唯一聚集索引可以指定列必须是复合键,即EmployeeID和TenantID都是PK??? - Matt
1
它会分解成这样,Employytable.employeeID将是一个非聚集的主键。然后,在tenantid和employeeid上创建一个组合聚集索引。例如:create table EmployeeTable ( employeeid int identity(1,1) primary key nonclustered, tenantid int, firstname varchar(200) --... and so on ) create unique clustered index IXCU__EmployeeTable__tenantId__EmployeeID on EmployeeTable (tenantid, employeeid) - Code Magician

1

对于利用您设计的多租户特性的每个查询,您都需要拥有一个包含tenantId的索引。问题是,在索引结构中tenantId应该出现在哪里?当然答案是取决于情况。尝试构建索引,使具有最大选择性的字段首先出现。

例如,假设一张表在50个州之间均匀分布(50),并且有10个租户,我会构建State,然后是TenantId的索引;对于具有1000个租户的相同表格,我会构建TenantId,然后是State的索引。

在实践中,这两个索引都可能很有用(让优化器来解决)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接