对于多租户的单个共享数据库,是否应将tenantid字段包括在主键和聚集索引中?或者只添加一个tenantid的额外索引同样高效?
我们正在生产系统上遇到性能问题,其唯一索引是主键上的聚集索引。
所有的SQL select语句都以tenantid开头,在它们的linq to entities语句中。
invoiceitems.tenantid = thecurrenttenantid order by invoicedate
当前架构
租户(tenantid uniqueidentifier primary key,tenantname) 外键(tenantid) 索引(按tenantid集群)
客户(tenantid uniqueidentifier,customerid uniqueidentifier primary key,customername varchar(50)) 外键(tenantid,customerid) 索引(按customerid集群)
发票(tenantid uniqueidentifier,invoiceid uniqueidentifier primary key,billcustomerid uniqueidentifier,shipcustomerid uniqueidentifier,invoicedate datetime) 外键(tenantid,billcustomerid,shipcustomerid) 索引(按invoiceid集群)
发票项目(tenantid uniqueidentifier,invoiceitemid uniqueidentifier primarykey,invoiceid uniqueidentifier,lineitemorder int) 外键(tenantid,invoiceid) 索引(按invoiceitemid集群)
SqlAzure要求每个表都有一个聚集索引,所以现在只有默认的主键索引。目前每个表上只有这一个索引。系统中各表中有各种外键,并且没有对任何外键表字段进行索引。
我们正在解决一些性能问题,想知道什么是最好的聚集索引,如果有其他索引可能会有帮助。我们希望不必改变现有的聚集索引,除非绝对必要,但我们愿意这样做。在SqlAzure中,据我所知,您无法简单地调整现有表中的聚集索引-您必须创建一个带有所需聚集索引的新表,并将旧表中的所有记录插入到新表中(并处理所有外键约束和其他表依赖项)。
所有SQL查询语句都以tenantid作为其Linq to Entities语句的开头。
invoiceitems.tenantid = thecurrenttenantid order by invoicedate
有些 SQL SELECT 语句只有一个排序 - 有些在引入子表时会有其他连接条件值,比如
invoiceitems.tenantid = thecurrenttenantid and invoice.invoiceid = invoiceitems.invoiceid order by invoicedate
以下是一些想法(除此之外,我们也欢迎其他建议)-哪一个最好,为什么?
主键索引选项
为了加快访问租户的记录
选项1-在tenantid上添加非聚集索引
Invoices (tenantid uniqueidentifier, invoiceid uniqueidentifier primary key, billcustomerid uniqueidentifier, shipcustomerid uniqueidentifier, invoicedate datetime) Foreign Keys (tenantid, billcustomerid, shipcustomerid) Indexes (clustered on invoiceid, non-clustered on tenantid)
选项2-将主键从primaryid更改为tenantid + primaryid,并将聚集索引更改为tenantid + primaryid。
Invoices (tenantid uniqueidentifier primary key, invoiceid uniqueidentifier primary key, billcustomerid uniqueidentifier, shipcustomerid uniqueidentifier, invoicedate datetime) Foreign Keys (tenantid, billcustomerid, shipcustomerid) Indexes (clustered on tenantid + invoiceid)
外键索引选项
为了加快联接速度
选项3-仅在foreignkeyid上的所有外键字段上添加非聚集索引。
Invoices (tenantid uniqueidentifier, invoiceid uniqueidentifier primary key, billcustomerid uniqueidentifier, shipcustomerid uniqueidentifier, invoicedate datetime) Foreign Keys (tenantid, billcustomerid, shipcustomerid) Indexes (clustered on invoiceid, non-clustered on billcustomerid, non-clustered on shipcustomerid)
选项4-将所有外键从foreignkeyid更改为tenantid + foreignkeyid,并在tenantid + foreignkeyid上添加索引
Invoices (tenantid uniqueidentifier, invoiceid uniqueidentifier primary key, billcustomerid uniqueidentifier, shipcustomerid uniqueidentifier, invoicedate datetime) Foreign Keys (tenantid, tenantid + billcustomerid, tenantid + shipcustomerid) Indexes (clustered on invoiceid, non-clustered on tenantid + billcustomerid, non-clustered on tenantid + shipcustomerid)
SQL SELECT优化索引选项
为了加快常用查询的速度,例如选择字段从发票中where tenantid = value order by invoicedate
选项5-在除tenantid之外的每个表中添加最常用排序字段的索引。
Invoices (tenantid uniqueidentifier, invoiceid uniqueidentifier primary key, billcustomerid uniqueidentifier, shipcustomerid uniqueidentifier, invoicedate datetime) Foreign Keys (tenantid, billcustomerid, shipcustomerid) Indexes (clustered on invoiceid, non-clustered on invoicedate)
选项6-在每个表中添加tenantid +“最常用排序字段”的索引,并在tenantid +“最常用排序字段”上添加非聚集索引
Invoices (tenantid uniqueidentifier, invoiceid uniqueidentifier primary key, billcustomerid uniqueidentifier, shipcustomerid uniqueidentifier, invoicedate datetime) Foreign Keys (tenantid, billcustomerid, shipcustomerid) Indexes (clustered on invoiceid, non-clustered on tenantid + invoicedate)