MySQL之语句优化
我打算从这一篇章开始说一说具体的sql语句的优化,希望大家可以在这一个篇章里面找到编写sql语句的感觉,也会在这里阐述一下为什么有些语句要这样子写才能把效率提高上来。这一个章节并没有什么系统化的东西,基本上都是本人平时在工作里面的积累,所以读起来可能会比较散,不过这不会影响大家对于sql语句优化的了解。
问题一:
很多程序员在编写sql的时候忽略了join,而使用了子查询,其实这样子是比较低效的做法。子查询在MySQL5.5版本里,内部执行计划器是这样执行的:先查外表再匹配内表,而不是先查内表t2,当外表的数据很大时,查询速度会非常慢。
例如:
SELECT * FROM record_maintable WHERE mainID IN (SELECT id FROM record_maininformation);
优化后:
SELECT * FROM record_maintable A Left JOIN record_maininformation B ON B.id=A.mainID
我们执行了两条语句对比发现,子查询语句执行时间0.022s,优化后的语句执行时间0.003s,优化后的效率明显比优化前高了好几倍。当数据量越大的时候这种优化会更明显。所以在这里作者建议大家,可以用join的千万不要用子查询的方案。
问题二:
有很多程序员在多条件查询的时候喜欢用OR,不过笔者在这里提醒一下的是,当你的语句的条件是同一个字段的时候,用IN去代替OR执行的效率会更加的高喔。
例如:
SELECT * FROM record_maintable WHERE ID=131 or ID=139 or ID=140
优化后:
SELECT * FROM record_maintable WHERE ID IN (131,139,140)
我们对比了同一个字段作为条件,用OR与用IN的区别是有多大了。用OR的执行效率不仅慢,而且对于接受你代码的那个小伙伴来说,代码更加难看懂。所以当满足上述调条件的情况下,作者更加推荐大家使用IN。效率更高,而且使得代码更加美观。
问题三:
很多人经常说,我的数据表里面已经添加了索引,为什么用起来的速度没有发生变化呢?答案是因为你们在搜索的时候用了左侧百分号。数据库一般都是前缀索引,所以支持模糊匹配在后面。因此你如果模糊搜索用了双百分号,索引就起不到作用,也就不能提高执行效率了。
我们现在做一个实验吧,有一张数据表已经加上了ID索引了。我们对比一下双百分号与右侧百分号的区别吧。
语句1:
SELECT * FROM record_maintable WHERE ID LIKE ‘%1%’;
语句2:
SELECT * FROM record_maintable WHERE ID LIKE ‘1%’;
从实验里面看双百分号的语句确实是没用使用到索引,因此效率比右侧百分号的模糊搜索速度要慢。在这里作者倡导大伙们,当你的数据表里面已经有了索引的时候,而且数据表中的数据比较多的时候,尽可能使用右侧百分号吧。这样子你能把执行效率提高一个档次。
问题四:
为什么别人拿一条数据的时候会比你快?因为你没有使用limit。很多时候写语句的程序员知道某一个条件的搜索只有一条数据,但是他们并没有加上limit1所以从效率上来说不如加了limit1的语句高效。因为即使某个搜索条件搜索出来的结果只有1条数据,但是如果你不加上limit1的话,sql还是会帮你全文搜索的。因此加上了limit的语句只要找到数量相同的数据时就会马上停止,而不会继续进行全文搜索,因此效率会更高一些。
例如:
SELECT * FROM record_maintable WHERE ID=131
优化后:
SELECT * FROM record_maintable WHERE ID=131 LIMIT 1
结果显而易见,加了limit的并没有做全文搜索因此效率会更高一些。
问题五:
很多程序员的插入语句分多条写,其实这样子的执行效率并不够单条插入语句高。所以在这里我推荐尽量使用一条语句插入的方法。
例如:
INSERT INTO record_tokenaddress (Path,CreateTS) VALUES (‘123/123’,’2018-11-24 18:13:38’);
INSERT INTO record_tokenaddress (Path,CreateTS) VALUES (‘456/456’,’2018-11-24 18:13:38’);
INSERT INTO record_tokenaddress (Path,CreateTS) VALUES (‘789/789’,’2018-11-24 18:13:38’);
优化后:
INSERT INTO record_tokenaddress (Path,CreateTS) VALUES (‘123/123’,’2018-11-24 00:00:00’),(‘456/456’,’2018-11-24 00:00:00’),(‘789/789’,’2018-11-24 00:00:00’);
大家看一下就知道了,执行多条语句跟执行一条语句的差距还是挺大的。所以在写sql的时候也要好好考虑好这个问题了。
总结:
Sql语句这里的优化我就用了5个例子表明sql的编写要注重好细节,多看看文档,多试试其他的写法,慢慢写多了,积累多了就能够写出更加好的sql了。这里的sql优化并没有捷径可走,必须靠自己一步一个脚印去积累吧。其实我在工作中对于sql的优化还是有一定的积累。但是也没有全部展示出来,因为实际情况要实际分析,不能生搬硬套。还是强调一下,多看看文档,多动动手试试不同的写法,你将会获益良多!
睿江云官网链接:https://www.eflycloud.com/home?from=RJ0032