针对SQL语句本身的查询优化

导读

现在项目愈加复杂的需求中越来越离不开数据库了。而实际项目中,查询往往占绝大多数。所以查询的优化是整个项目的关键。由于系列教程还只是刚开始,所以这里的优化只涉及SQL语句本身,而不涉及索引优化、引擎选择等进阶操作。

复习

在我之前写的SQL基础中,描述了SQL语句的执行顺序,还是那个手办的例子:

SELECT DISTINCT 手办表.对应人物, 手办表.服饰, 手办表.价格, 番剧表.番剧名称, 番剧表.出场人物
FROM 手办表, 番剧表
WHERE 手办表.对应人物 = 番剧表.出场人物
GROUP BY 手办表.对应人物, 手办表.服饰, 手办表.价格, 番剧表.番剧名称, 番剧表.出场人物
ORDER BY 手办表.价格 DESC;

按照之前的顺序,我们一步一步分析:

FROM

我们将会把FROM后面跟着的所有的表全部加载到内存。听起来是为了方便筛选数据,但是这么做对于海量数据的表将会是毁灭性的。就单纯的像学生管理系统的学生表,涉及姓名、密码、民族、政治面貌、入学时间、毕业时间、奖惩记录等等可能上百个字段,几万行数据,相当的消耗内存。即使现在MySQL数据库最大只支持1000个字段,在几万学生面前依然是一个不小的数据量。如果真的是联立表,推荐使用JOIN进行联立。下面便是JOINON的介绍。

JOIN&ON

ON将会在联立两个表的数据之前仅加载一张表的数据,然后另一张表通过一定的条件合并到第一张表中,相对于直接联立会减小很多压力。所以,本例中的SQL语句可以修改为:

SELECT DISTINCT 手办表.对应人物, 手办表.服饰, 手办表.价格, 番剧表.番剧名称, 番剧表.出场人物
FROM 番剧表
LEFT JOIN 手办表
ON 手办表.对应人物 = 番剧表.出场人物
GROUP BY 手办表.对应人物, 手办表.服饰, 手办表.价格, 番剧表.番剧名称, 番剧表.出场人物
ORDER BY 手办表.价格 DESC;

虽然本例中查询的结果是一样的,但是查询过程也略有差别。这是因为LEFT JOIN会保留左表所有字段,即使不匹配也将显示在结果中。在之后的进阶操作将会详细展开;不仅如此,两者在查询时间上也略有区别,但是这里数据实在太少,区别不明显。如果是查询中国街道表将会有非常明显的变化。

WHERE

WHERE作为筛选条件,虽然说没有非常明显的优化方式,但是还是想说:尽量少用字符串作为匹配条件。在匹配的时候往往会整个串遍历,时间复杂度最少也是KMP算法的 O ( m + n ) O(m+n) O(m+n),而数字则为 O ( 1 ) O(1) O(1),相对来说会少一个数量级的复杂度。不过如果字符串很短,例如学号、教工号这类不超过15个字符的就随意了。

GROUP BY&HAVING

GROUP BYHAVING作为分组条件没有什么可以优化的了,只能说根据业务需求进行调整。分很多组便会每组很少的人;而分很少组则每组很多人,如果不联系实际需求将很难平衡这两个选择。

SELECT

SELECT将会从内存中选择列,这没什么争议。但是如果使用*作为属性列表将会让系统首先查找哪些字段符合条件,也将消耗资源。哪怕表内几百的字段都是需要查询的,最好也要一个个写上去。

DISTINCT

只是普通的剔除重复的,因为大量重复的情况很少出现,所以如果不是为了特殊业务有或无都没什么。要说为什么?只能说“我相信前端工程师所给的输入限制”。虽然是很无赖的甩锅行为,但是百用不厌(笑)。

ORDER BY

正如我们在SQL基础中说明的一样,数据库会根据索引优化树形结构。所以,排序的优化就转变为了索引的优化。这就是另外一门学问了。

索引优化

看起来和SQL语句完全没有关系,实际上正如上面ORDER BY一栏所述,优化结构使得查询更为便捷也是优化的一种。

MySQL支持的最大索引数量是57个,但是实际上最好还是不超过5个,因为过多的索引不便于表结构专门针对某一个字段优化,正所谓“过犹不及”。

索引优化并没有一个定性公式,而是根据需求和实际不断权衡、各取利弊,最终达到极限。依然举个有些乱来的例子:

你找到了一家手办店。你相当的喜欢这里面的手办,每一款都非常好看。但是因为你当前的经济能力由不得你全都要,只能购买其中最喜欢的几个。所以店长专门为整个手办店创建了索引。

说是创建索引,实际上也是根据番剧名称重新分类、重新整理数据结构而已。于是你在找你喜欢的手办(数据库查询)的过程中,你发现你头顶有一些标牌,标明了哪些区域是哪些番剧(根据番剧创建的索引)。

于是你根据这些标语找到了《Re:从零开始的异世界生活》。

但是蕾姆人气实在是太高了,魔术师、泳装、女仆装、便装、睡衣装、等身手办等等都一一展示在这个区域。于是店长精心整理了一下这里的展示柜,从下到上模型逐渐变得小巧、服饰逐渐变少;从1:4逐渐过渡到1:8(根据模型大小创建的索引),从羽绒服逐渐过渡到浴巾(根据服饰创建的索引)。这么一整理是不是比胡乱摆放的仓库好多了?

是不是有点能理解了呢?

文章索引(手动)

上一篇:SQL基础

下一篇:待补充,敬请期待

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ordinary_brony

代码滞销,救救码农

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值