比如,我有个字段是 level ,然后这个 level 在数据表里,就是 1,2,3,4 这 4 个值
那么,我查询的时候,写了一个语句 where level in (1,2,3,4)
mysql 会自动优化不,和 没有这个 level 条件比,查询性能怎么样呢
谢谢大家
主要是没想到怎么去测试这个,写大量的数据,然后看不加条件和加了条件的查询耗时?
1
awalkingman 2023-03-31 20:11:24 +08:00
有一种情况有用。假设索引是( name ,level ,age ),查询条件 where name=“” and level in ( 1234 ) and age=“”,这个时候会走索引,但其实只需要 name 和 age 的条件,其实就是想办法利用最左前缀。
expain 看一下计划,或者 trace 看一下查询成本。 |
2
fds 2023-03-31 20:31:35 +08:00
没可能优化吧,数据库怎么知道表里只有 4 个值。数据库主要耗时在 IO 的话,你这种无效的语句就是多了一步查询后的校验,我觉得不会浪费什么时间。
|
3
thinkershare 2023-03-31 21:06:15 +08:00
我估计并没有办法优化你说的这种情况,加了 in 以后,即便 level 有索引也会变慢,不过你这种有索引就是个复杂的 n 的算法,基本对性能影响可以忽略,但是肯定比没有这个条件要慢,因为加载索引,比较需要时间的。你可能认为 mysql 会去分析列的所有有效值,然后去掉这个 in 操作,我估计 mysql 的优化器不会去做这件事。不过具体来说,我也没有去了解最新的 mysql 优化器的设计,等一位大神来解答。
|
4
liuxu 2023-03-31 21:30:08 +08:00
in 里面是标量或者唯一索引的子查询没啥问题,能用到 level 上的索引就行,但要注意 in 里面的项数不要超过 eq_range_index_dive_limit 设置的值,mysql5.7 和 mysql8 中都是 200 https://www.liuquanhao.com/posts/mysql%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%99%A8%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/#%E6%A0%87%E9%87%8F%E5%AD%90%E6%9F%A5%E8%AF%A2
|
5
zlowly 2023-04-01 13:26:58 +08:00
在 MySQL 8 或者 MariaDB 10 以上,如果你这个表有做表分析(ANALYZE TABLE),那么是有可能的。表分析出来的统计数据会有直方图( Histogram ),从而给优化器提供估计查询谓词的选择率,就像你的例子里,走索引的花销还不如全表,执行计划里就会放弃这个索引。
|
6
lotusgrm 2023-04-21 14:44:38 +08:00
从你的描述来看,level 是一个枚举类型的数据,mysql 在处理枚举类型数据时,会将其转换为整型进行处理,以提升其查询性能,但是由于枚举类型的值索引选择性比较低,因此这种优化的效果可能比较小
|