记一次MySQL Group by 的坑
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次MySQL Group by 的坑相关的知识,希望对你有一定的参考价值。
参考技术A 表结构如下:业务需要将表中重复数据删除,所以需要按照 组合唯一索引键筛选出重复的数据进行删除。SQL如下:
表中有符合索引 KEY column1_column2_index ( column1 , column2 )
sql语句 Group by 也是按照最左匹配原则顺序写的 group by 的字段,但是每次执行SQL耗时都是好几十秒
explain 该 sql 发现,并没有走表中存在的复合索引,而是直接走的 File sorted(文件排序);group by 语句其实是有要先排序再分组的;
问题的关键定位到没有没有命中表中的复合索引,那为何 group by 字段前两个就是复合索引,只是最后两个不是,为何没有走索引呢?不是索引只要满足最左匹配原则就可以命中吗?
分析后发现,索引可以用在两个地方,1 被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度。2 快速地执行ORDER BY和GROUP BY语句的排序和分组操作。
本处就是可以使用索引做排序使用,而避免文件排序;此处要命中索引,走索引排序,必须要表中有一个复合索引包含 group by 的所有字段且顺序一致;
网上有部分博客说 group by 自带的排序和 order by 排序,走不走索引的规则是一样的,这里本人测试了一下,添加 group by 后面所有顺序字段的复合索引对 group by 的查询时间有直接的影响,从 30多秒 优化到 3秒;
但是对如下SQL 的执行时间也有影响,但是远远没有对group by 的影响大,如下sql,添加 order by 的全索引后 只能从30多秒优化到 10 多秒
select column2 from am_cm_relationship order by column1,column2,column3,column4 ;
strposphp的strpos的坑,记一次
php > var_dump(strpos(‘开始23测试ceshi‘, ‘测试‘)); int(8) php > var_dump(mb_strpos(‘开始23测试ceshi‘, ‘测试‘)); int(4) php > var_dump(strpos(‘123测试ceshi‘, ‘测试‘)); int(3) php > var_dump(mb_strpos(‘123测试ceshi‘, ‘测试‘)); int(3) php > var_dump(strpos(‘测试23aac‘,‘3‘)); int(3) php > var_dump(strpos(‘测试23aac‘,‘a‘)); int(4)
右上可知:如果查找的字符串是 【汉字】,那么长度就以 utf-8格式,记3,;
如果查找的字符串是【非汉字】,那么长度记 1 ;
以上是关于记一次MySQL Group by 的坑的主要内容,如果未能解决你的问题,请参考以下文章
MySQL从入门到精通高级篇(三十)记一次mysql5.7的新特性derived_merge的坑