对于多租户的单一共享数据库,tenantid字段是否应该包含在主键和聚集索引中?或者,在tenantid上添加一个额外的索引也是一样的吗?
我们在生产系统上遇到性能问题,该系统的唯一索引是主键上的聚集索引。
所有sql select语句在其linq to entities语句中以tenantid开头,如
invoiceitems.tenantid = thecurrenttenantid order by invoicedate当前模式
租户(tenantid unique标识符主密钥,tenantname)外部密钥(tenantid)索引(集中在tenantid上)
客户(tenantid unique标识符,客户标识符,主键,customername varchar(50))
发票(tenantid unique标识符,invoiceid unique标识符主键,billcustomerid unique标识符,付运客户标识符,invoicedate日期时间)
InvoiceItems (tenantid unique标识符,invoiceitemid primarykey,invoiceid unique标识符,lineitemorder int) Foreign (tenantid,invoiceid)索引(聚集在invoiceitemid上)
SqlAzure要求每个表都有一个聚集索引,因此它目前只在主键上,因为这是默认的。现在,这是每个表上的唯一索引。整个系统的表中都有不同的外键,而且没有对外键表字段进行索引。
我们现在正试图解决一些性能问题,并想知道什么是最好的聚集索引,以及是否有其他索引可能有帮助。我们希望我们不必改变现有的聚集索引,除非我们绝对必要,但我们愿意这样做。在SqlAzure AFAIK中,您不能简单地调整现有表中的聚集索引--您必须使用所需的聚集索引创建一个新表,并将旧表中的所有记录插入到新表中(并处理所有外键约束和其他表依赖项)。
所有select语句在其linq实体语句中以tenantid开头。
invoiceitems.tenantid = thecurrenttenantid order by invoicedate有些sql select语句只是有顺序--有些语句在引入子表时具有其他联接条件值,如
invoiceitems.tenantid = thecurrenttenantid and invoice.invoiceid = invoiceitems.invoiceid order by invoicedate以下是一些想法(除了这个之外,我们对其他人开放)--,哪些是最好的,为什么是
主键索引选项
加快房客记录的存取速度
选项1-在tenantid上添加一个非聚集索引
发票(tenantid unique标识符、invoiceid unique标识符主键、billcustomerid unique标识符、发货人客户标识符、invoicedate日期时间)
选项2-将主键从主键改为tenantid +主键,并将聚集索引更改为tenantid + primaryid.
发票(tenantid unique标识符主键、invoiceid unique标识符主键、billcustomerid unique标识符、付运客户标识符、发票日期时间)外部密钥(tenantid、billcustomerid、shipcustomerid)索引(聚集在tenantid +上)
外键索引选项
加速连接
选项3-仅在foreign key .上对所有外键字段添加非聚集索引
发票(tenantid unique标识符,invoiceid invoiceid主键,billcustomerid unique标识符,发货人clustered unique标识符,invoicedate datetime)
选项4-将所有外键从foreignkeyid改为tenantid + foreign keys,并在tenantid +foreign keys上添加索引
发票(tenantid unique式标识符,invoiceid unique式标识主键,billcustomerid unique式标识符,付运clustered unique标识符,invoicedate日期时间)
SQL选择优化索引选项
为了加快速度,经常使用的查询如从发票中选择字段,其中tenantid = value order按invoicedate
选项5-除了tenantid.之外,在每个表中添加最常用的排序顺序字段的索引
发票(tenantid unique标识符,invoiceid unique标识符主键,billcustomerid unique标识符,发货人客户标识符,invoicedate日期时间)
选项6-在每个表中添加对tenantid +“最常用的排序顺序字段”的索引,并在tenantid +“最常用的排序顺序字段”上添加非聚集索引“”
发票(tenantid unique标识符、invoiceid invoiceid主键、billcustomerid unique标识符、付运客户on unique标识符、invoicedate日期时间)
发布于 2013-02-12 02:50:59
看来你已经想了很多了。不管我或其他人说什么,唯一能确定的方法就是自己测量。在这种情况下,这不再是SQL Azure问题,而是更多的一般SQL Server查询优化问题。
对于你的情况,有几个提示可以让你开始。在使用LINQ时,您无法直接访问在SQL中运行的实际查询。您可能认为您知道查询应该是什么样子,但取决于您使用的EF版本,它可以就如何构造查询做出一些有趣的决定。要确切地了解正在运行的查询,您需要使用SQL或扩展事件。server对SQL不起作用,所以您要么需要使用扩展事件,要么需要在某个本地服务器上获取DB的副本,然后运行指向本地的应用程序。导出数据层应用程序和(SSMS)中的相关导入对此非常有用。
使用实际的查询,您可以在SSMS中针对Azure中的数据库运行它们,以获得执行计划。然后可以对索引进行更改,再次运行查询并比较计划。如果您不想搞乱您的主开发DB,您可以很容易地使用在许多方面创建一个副本,包括使用CREATE DATABASE xxx AS COPY OF yyyy命令。
不要试图在本地DB上进行优化。SQL的性能大纲与大多数前提SQL安装不同。
尽管如此,如果您的所有查询总是包含租户ID,那么是的,我希望将它作为聚集索引的第一部分将提高查询性能。对于所有其他的索引,我不太确定,所以我会测量,测量,测量。还请记住,索引并不是免费的,您创建的每个索引都会对您的写性能和数据库大小产生影响,所以我不会疯狂地对所有内容进行索引。
最后,不要担心对PKs使用guids,如果您的DB变得足够大,您需要通过租户ID (您的结构看起来会很好地处理这个ID)来联合它,那么身份列就不再成为一种选择。
发布于 2013-02-12 03:24:04
我同意@knigtpfhor的回答,但我要补充的是,如果您打算在SQL中使用Federations,您需要将联邦键(TenantID)作为联邦成员中每个表聚集索引的一部分。(你上面的选项2)。有关更多详细信息,请参阅联合会的指导方针和限制。
我绝对会在您的表上添加额外的非聚集索引;选择要索引的字段是一种科学,也是一种艺术,但我通常尝试从回顾我可能发出的查询开始,并确保我有一个涵盖相关字段的索引。我的预感是,虽然您的主键\ Foreign是索引的,但它们在所有情况下都可能与实际查询数据的方式不相关。
您正在经历什么样的性能问题?您是否存在写入数据或查询数据的问题,还是两者兼而有之?这个数据库有多大?您的性能问题是间歇性的还是相当一致的?
https://stackoverflow.com/questions/14729094
复制相似问题