我的一个函数昨天上线了,测试环境中的数据量很小,所以问题不大。然而,在生产之后,它被直接阻止,然后开始了这样的SQL优化。这是一张唱片。
要揭示公司的表结构并不方便,这里我构建了几个表,并对其进行了模拟。
购买清单:
采购结算单:
发票表:
发票及报表相关表:
以上是我自己创建的几个表,首先介绍这些表之间的关系:
购买列表关联。值得注意的是:
一个采购订单可以通过关联对应多个采购报表,例如以下数据:
一个采购报表可以对应多个采购订单。通过关联,表中的字段存储多个采购订单编号,这些编号用逗号分隔。如下所示:
发票表
发票表和关联表使用和关联
语句表和关联表使用关联
发票和报表是多对多的
现在,您需要使用购买报表表查询列表:
列表字段为采购平均单价、计划采购总额、结算编号、结算平均单价、结算金额、结算时间、发票编号、发票代码
查询条件为:采购时间当一个采购账户对应多个采购票据时,只要在范围内有一个采购票据的时间,查询到、结算时间、发票号当一张结算票据对应多个发票时,只要有发票可以关联,查询到
按结算时间排序
当然,当时的实际需求有更多的列表字段,更多的查询项。。。
首先在每个列表中插入100000条数据,我使用存储过程:
调用存储过程以生成数据:
生成后,需要随机修改几条数据。一份采购订单可以对应多个采购报表,一份采购报表可以对应多份采购报表。
一个采购订单可以对应多个未模拟的采购报表,这种情况对查询影响不大。
一份采购报表可以对应多份采购报表:
。
创建一些发票数据和报表-发票关联数据,以反映多对多关系:
当然,优化的第一步是要求产品经理删除一些查询条件,这样采购清单就不会与采购资产负债表相关联,但您会想到。。
这里以采购时间作为条件查询为例因为它主要是采购清单和采购对账单的关联导致查询速度慢,记住需求哦,它是一个采购对账单,可能对应多个采购清单,只要在时间范围内有一个采购单,就需要查询出这个采购对账单
另外:我在上面创建的表中的索引模仿了优化之前的索引
4.1第一版
SQL的第一个版本在本地环境中执行大约需要5秒,到那时它已经意识到了问题,更不用说生产了,并且将在测试环境中失败。
但看看我是如何在自己的垃圾服务器上运行这条SQL的,它没有工作虽然公司的服务器更好,但生产环境真的卡住了:
。
当时还没有看到执行计划,一目了然,这种SQL使用了,肯定不会去索引,构建索引是没用的,也就是说,主要是购买表表和购买语句表的关联会很慢,毕竟它们是多对多关系,再加上这种恶心的需求。所以现在想想怎么不去做。
是的,在吃饭的时候,我突然有了一个想法:我应该能够将采购报表表拆分成一个临时表,如果采购报表表对应五个采购订单,我会将采购报表拆分成五个数据,这五个数据除了采购订单号不同之外,其他字段都是相同的,因此无法使用。
我们做到了,这是SQL的第二个版本。
4.2第二版
要将采购报表表拆分为上述临时表,我们需要添加一个表:
让我们来看看如何将采购对账单数据拆分为多个:
为了解释操作:
首先,我创建了一个只有ID的表,插入了十条数据,这十条数据必须是1-10。
然后我使用正确的连接,只获取ID小于或等于采购订单数量的数据。这控制了SQL应该查询多少数据。
然后在拆分表中逐个使用采购订单编号
此SQL执行的结果是:
。
把它们放在一起,您就有了SQL的第二个版本:
测试查询数据结果一定没问题哦!!
好了,在这一点上,我们终于摆脱了所有我们使用的地方,现在看看索引是有意义的!
看看执行计划:
。
Asiba,一堆完整的表扫描,看看上面的第二个版本的SQL,发现传入的表字段应该被索引,根据这个字段的原则,在一般的表设计中应该被添加到索引中,但我认为它只是我认为,它没有添加到索引,好的,然后将它添加到索引:
添加此索引后,请查看执行计划:
该表已被索引,但为什么不索引,它有两个索引。。
。
让我们看看它是否适用于我的垃圾邮件服务器:
。
好了,让我们开始下一轮SQL优化,以使表查询具有索引
4.3第三版
不要将下面的总和相加,而是将上面的总和相加。要使用这两个字段作为查询条件,您可以将以下SQL包装为临时表,然后再次查询它,这里将不再演示
看看执行计划:
。
至此,基本优化结束,请查看我的垃圾邮件服务器上的结果:
。
在这里,基本上生产可以在三秒内查询,这个SQL优化已经结束!!
然而,仍然有可能继续优化设计,但设计在系统中有很多变化,这对系统有很大的影响。以下是一些暂时无法实施的想法:
可以购买表和购买资产负债表,建立中间表之间,实现多对多关系,尝试再次索引,应该更快,并且可以一劳永逸,之后这种关联会更方便!
1d 列表字段为采购平均单价、计划采购总额、结算编号、结算平均单价、结算金额、结算时间、发票编号、发票代码
发表评论