数据库设计 – MultiTenant表是否在主键和外键中包含TenantID?
对于多租户单一共享数据库,应将tenantid字段包含在主键和聚簇索引中?还是在tenantid上添加额外的索引呢?
我们正在生产系统上遇到性能问题,其中唯一的索引是主键上的聚簇索引. 所有的sql select语句都是以他们的linq中的tenantid开头的实体语句 invoiceitems.tenantid = thecurrenttenantid order by invoicedate 当前图 租户(tenantid uniqueidentifier主键,租户名) 客户(tenantid uniqueidentifier,customerid uniqueidentifier主键,customername varchar(50)) 发票(tenantid uniqueidentifier,invoiceid uniqueidentifier主键,billcustomerid uniqueidentifier,shipcustomerid uniqueidentifier,invoicedate datetime) InvoiceItems(tenantid uniqueidentifier,invoiceitemid uniqueidentifier primarykey,invoiceid uniqueidentifier,lineitemorder int) SqlAzure要求每个表都有一个聚簇索引,所以它目前只是在primarykeyid,因为这是默认的.现在这是每个表上唯一的索引.在整个系统的表中有各种外键,并且没有一个外键表字段被索引. 我们现在正在尝试解决一些性能问题,并且想知道什么是最好的聚集索引,以及任何其他索引可能是有帮助的.我们希望我们不必改变现有的聚集索引,除非我们绝对必须,但我们愿意这样做.在SqlAzure AFAIK中,您不能简单地调整现有表中的聚簇索引 – 您必须使用所需的聚簇索引创建一个新表,并将所有记录从旧表插入新表(并处理所有外键约束等)表依赖性). 所有的sql select语句都以tenantid开头,在他们的linq到entity语句中. invoiceitems.tenantid = thecurrenttenantid order by invoicedate 一些sql select语句只是有一个顺序 – 有些在引入子表时有其他连接条件值 invoiceitems.tenantid = thecurrenttenantid and invoice.invoiceid = invoiceitems.invoiceid order by invoicedate 这里有几个想法(除了这个外,我们对其他人开放) – 哪些是最好的,为什么? 主要指标选项 加快租户记录的访问 选项1 – 在tenantid上添加非聚集索引 发票(tenantid uniqueidentifier,shipcustomerid) 选项2 – 将主键从primaryid更改为tenantid primaryid,并将集群索引更改为tenantid primaryid. 发票(tenantid uniqueidentifier主键,shipcustomerid) 外国主要索引选项 加快连接 选项3 – 仅在foreignkeyid上的所有外键字段上添加非聚集索引. 发票(tenantid uniqueidentifier,shipcustomerid) 选项4 – 将所有外键从foreignkeyid更改为tenantid foreignkeyid,并在tenantid foreignkeyid上添加索引 发票(tenantid uniqueidentifier,tenantid billcustomerid,tenantid shipcustomerid) SQL SELECT优化索引选项 加快经常使用的查询,如从发票的选择字段,其中tenantid = value order by invoicedate 选项5 – 除了tenantid之外,在每个表格中最常使用的排序顺序字段中添加索引. 发票(tenantid uniqueidentifier,非集群在发票上) 选项6 – 在每个表格中的tenantid“最常用的排序顺序字段”中添加索引,并在tenantid“最常用的排序顺序字段”上添加非聚集索引 发票(tenantid uniqueidentifier,非聚簇在开发票单上) 解决方法看来你已经给了很多想法.无论我或任何人说什么,唯一的知道方法是自己测量.在这种情况下,这将减少SQL Azure问题和更多的一般SQL Server查询优化问题.对于你的情况,有几个提示让你开始.当您使用LINQ时,您无法直接访问在SQL中运行的实际查询.您可能会认为您应该看到什么样的查询,但根据您使用的是哪个版本的EF,可以对如何构建查询做出一些有意思的决定.要准确找出正在运行的查询,您需要使用SQL Profiler.不幸的是,SQL Profiler不适用于SQL Azure,因此您将希望在某个本地服务器上获取您的数据库副本,并运行您的应用程序指向本地. SQL Server Management Studio(SSMS)中的export data tier application和相关import对此非常有用. 通过实际查询,您可以使用Azure中的数据库在SSMS中运行它们以获取执行计划.然后,您可以更改索引,再次运行查询并比较计划.如果你不想混淆你的主开发数据库,??你可以很容易地用CREATE DATABASE xxx AS COPY OF yyyy创建一个副本. 不要试图在本地DB上进行优化. SQL Azure具有与大多数内部SQL安装不同的性能轮廓. 所有这一切都表示,如果您所有的查询总是包含租户ID,那么是的,我希望将其包含为群集索引的第一部分可以提高查询性能.对于所有其他索引,我不太确定,所以我会衡量,衡量,测量.还要记住,索引不是免费的,每一个你创建的影响你的写性能和数据库的大小,所以我不会坚持和索引的一切. 最后,不用担心为你的PK使用guids,如果你的DB足够大,你需要通过租户ID(你的结构看起来像处理相当不错)IDENTITY列停止成为一个选项. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |