mysql 优化-数据类型不匹配导致的全表扫描

Posted 信行合一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 优化-数据类型不匹配导致的全表扫描相关的知识,希望对你有一定的参考价值。

一条sql执行时间特别长,很多时候页面都直接504 timeout,sql内容大致如下,其中a表的数据有2000w+数据,b表有600w+数据

SELECT
	a.*
FROM
	 a
WHERE
	a.user_id = 123
AND a.id NOT IN (
	SELECT
		b.pay_record_id AS pay_record_id
	FROM
		 b
	WHERE
		b.user_id = 456
)
ORDER BY
	create_time DESC;

本来这2条sql语句里面都是有索引的,所以查询速度应该是很快的,但是实际上慢到直接超时,有点不解。
于是把每条sql都单独执行一下,发现速度很快,但是放到一起就很慢,于是就知道问题出在了2个表的关联条件上了。

于是查看了 a表的id的字段类型为 int,而b表中pay_record_id是bigint。这就找到原因了,a表和b表的字段类型不匹配,所以导致了a表的全表扫描。所以超时!
解决办法就是为b表的字段进行类型转换 ,让它跟a表的字段类型一致,修改后sql如下:

SELECT
	a.*
FROM
	 a
WHERE
	a.user_id = 123
AND a.id NOT IN (
	SELECT
	-- 把 bigint 转换为 int
		cast(b.pay_record_idas signed)  AS pay_record_id
	FROM
		 b
	WHERE
		b.user_id = 456
)
ORDER BY
	create_time DESC;

执行一下发现执行时间从超时变成2-3秒,完美解决问题。

解决思路:
单独分析每一条sql执行时间,如果有特别慢的sql那么先优化单独的sql,如果单独执行sql速度很快,那么问题就应该出现在表管理的条件上,表关联条件慢一般就是数据类型不匹配:包括 int 跟 bigint不匹配,varchar的字符集不匹配都可能导致全表扫描。

以上是关于mysql 优化-数据类型不匹配导致的全表扫描的主要内容,如果未能解决你的问题,请参考以下文章

警惕 Oracle 索引优化时陷阱之无效的索引范围扫描(INDEX RANGE SCAN)导致的全表扫描

Mysql 索引优化

Oracle SQL优化必要的全表扫描思路分析

MySQL索引基础补充以及优化笔记-下

MySQL优化Explain命令简介

MYSQL性能调优03_在什么情况下会导致索引失效从而进行全表扫描