SQL 语句执行较慢的 3 个原因
没有建立索引,或者索引失效导致了 SQL 语句执行较慢
这个应该是比较好理解的,如果数据比较多,在千万级别以上,然后呢又没有建立索引,在这千万级别的数据中查找你想要的内容,简直就是在肉搏啊(哎呦,可了不得,竟然敢肉搏
索引失效这块内容说起来就比较多了,比如在查询的时候,让 like 通配符在前面了,比如经常念叨的“最左匹配原则”,又比如我们在查询条件中使用 or ,而且 or 前后条件中有一个列没有索引,等等这些情况都会导致索引失效
锁等待
常用的存储引擎主要有 InnoDB 和 MyISAM 这两种了,前者支持行锁和表锁,后者就只支持表锁
如果数据库操作都是基于表锁的话,意思就是说,现在有个更新操作,就会把整张表锁起来,那么查询的操作都不被允许,所以就不要说提高系统的并发性能了
- 聪明的你肯定就知道了,既然 MyISAM 只支持表锁,那么使用 InnoDB 不就好了?你以为 InnoDB 的行锁不会升级成表锁嘛?too young too simple !
- 如果对一张表进行大量的更新操作, mysql 就觉得你这样用会让事务的执行效率降低,到最后还是会导致性能下降,这样的话,还不如把你的行锁升级成表锁呢
- 还有一点,行锁可是基于索引加的锁,在执行更新操作时,条件索引都失效了,那么这个锁也会执行从行锁升级为表锁
不恰当的 SQL 语句
这个也比较常见了,啥是不恰当的 SQL 语句呢?就比如,明明你需要查找的内容是 name , age ,但是呢,为了省事,直接 select *
,或者在 order by 时,后面的条件不是索引字段,这就是不恰当的 SQL 语句
优化 SQL 语句
在知道了 SQL 语句执行比较慢的原因之后,接下来要做的就是对症下药了
针对 没有索引/索引失效 这块,最有效的办法就是 EXPLAIN 语法了,那你知不知道 Show Profile 也可以嘞
针对 锁等待 这块,没办法了,只能自己多注意
针对 不恰当的 SQL 语句 这块,介绍几个常用的 SQL 优化,比如分页查询怎么优化一下可以查询的更快一些呀,你不是说 select *
不是正确的打开方式嘛?那什么是正确的 select 方式呢?别急嘛,阿粉下面都会说到的
废话不多说,咱们开始了
先来个表
为了确保优化后的结果和我写的一样(起码 90% 是相符的
所以咱们用一样的数据库好不好?乖~
首先建个 demo 的数据库
接下来咱们建表,就建个非常简单的表好不好
CREATE TABLE demo.table( id int(11) NOT NULL, a int(11) DEFAULT NULL, b int(11) DEFAULT NULL, PRIMARY KEY(id) ) ENGINE = INNODB
然后插入 10 万条数据
DROP PROCEDURE IF EXISTS demo_insert; CREATE PROCEDURE demo_insert() BEGIN DECLARE i INT; SET i = 1; WHILE i <= 100000 DO INSERT INTO demo.`table` VALUES (i, i, i); SET i = i + 1 ; END WHILE; END; CALL demo_insert();
OK ,准备工作做好了,接下来开始实战