ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

工作中遇到的bug(记录一下)

2021-11-17 16:01:43  阅读:103  来源: 互联网

标签:index 遇到 记录 bug 索引 sql MySQL ref id


 与其说是bug,倒不如说是自己的失误。

背景:php代码重构为go语言beego项目,重构完后,对部分接口进行压测,发现某个接口qps一直上不去,响应时间非常高。经过排查发现是数据库查询花了很多时间。

表是一张两千万张数据的表。有建立索引

sql如下:

SELECT
user_id,count(1) as count
FROM
star_fans
WHERE flag=1 and user_id in (
2165,286,2471,3052892,13582,1351
)
GROUP BY user_id

通过explain sql 分析sql 发现Select_type 为index 

根据这个命令的相关字段详解发现:

表示MySQL在表中找到所需行的方式,又称“访问类型”。

常用的类型有: ALL, index,  range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)

Select_type 说明查询中使用到的索引类型,如果没有用有用到索引则为all

ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

index: Full Index Scan,index与ALL区别为index类型只遍历索引树

range:只检索给定范围的行,使用一个索引来选择行

ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件

const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system

NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

其中row居然是完整的2000w条数据,意味着等于全表扫描了。

所以非常疑惑,况且对索引的理解不是很深,看了表结构,发现索引建立的也没问题。况且php中也是使用同样的sql,它的接口却访问的很快。

后面几经排查,发现是由于sql中数据类型不对导致的,string类型没有加引号,php为弱类型语言,可能orm框架中有对其进行优化。

果不其然,sql改为:SELECT
user_id,count(1) as count
FROM
star_fans
WHERE flag=1 and user_id in (
'2165','286','2471','3052892','13582','1351'
)
GROUP BY user_id

再通过explain sql发现 select_type变成了range ,同时rows变成几万条而不是两千万条

 总结:在写业务代码时或者重构时,要注意不同语言的差异,以免踩坑,虽然不加引号也能查出来,但是效率却是千差万别,足以说明压测的必要性,以及写代码时的严谨性,可以运行是一回事,写出优秀的代码更是不容易。

 

标签:index,遇到,记录,bug,索引,sql,MySQL,ref,id
来源: https://www.cnblogs.com/sherry-blog/p/15567678.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有