慢查优化,不走索引

mysql隐式转换造成不能使用索引的场景:

1、数据类型不一致:
查询传入的where字段类型与被索引的字段类型不一致,或者两个表的连接字段类型不一致时,一般会进行隐式转换(自动使用cast()函数),无法使用索引。如字段fownerid varchar类型的,查询使用int类型值,where fownerid=41354223837004801,可以改成 where fownerid=‘41354223837004801’

2、字符集不一致:
当两个表的连接字段字符集不一致时,一般会进行隐式转换(自动使用convert()函数),无法使用连接字段的索引。mysql在实例级、库级、表级、列级都可以定义字符集。

执行计划查看时有warning信息,可以查看具体情况。

2 个赞

我这个也是后面加的,加的时候没注意统一

字符集和排序规则不一样执行计划可能就有问题。
另外你可以把涉及的表都手工analyze一遍

首先,确保统计信息是最新的。执行计划会受到统计信息影响。如果统计数据是最新的,那么说明tidb觉得走索引后再filter(tidb可能没有filter的概念,只有select的概念)的cost比直接全表的cost要大。单机数据库时候,从estRows数值上看,肯定应该是走index更科学更快。但根据我目前对tidb的接触,它往往会认为分布式计算能够带来更快速的执行。所以,tidb更偏向于选择下推。从我的实践来看,似乎下推的计算能力并不强,可能是因为当tidb server和tikv的配置相同时候,tikv的任务比tidb server更加繁重。而且有些公司为了省钱,提高可用性,会在一台tikv创建多个store,进一步降低了下推的性能。

:flushed:这个有点天坑啊,感觉没有什么能够规避的,只能要求部署规范、开发规范。

1 个赞

后面加个巡检项,提前发现吧

:thinking:确实得巡检一下

学习了,是字符集的问题

子查询,优化器不是可以自动改为关联查询的么

同感。应该设置默认utf8mb4_bin作为默认排序规则,建表语句不带charset子句。

之前也遇到过同样问题

前期发现还好,数据量大了改动都麻烦

修改列上的排序规则,需要先删除该列上的索引,如果业务正在用和表很大,还得停机维护

想想就头疼, :sweat_smile:

这位老兄说得很细,点个赞

改执行计划也行

额。这和mysql当中的问题一样。如果是字符集的问题的话

以前碰到字符集不同索引失效的,排序规则不同也会导致索引失效呀。一般最好还是统一字符集和排序规则吧。

记录,防坑。

对,一定要建表规范,不能寄希望于默认字符集和默认排序规则,建表时该指定的,一个都不能漏