Mysql 不使用包含两列的索引
Posted
技术标签:
【中文标题】Mysql 不使用包含两列的索引【英文标题】:Mysql not using an index on where in with two columns 【发布时间】:2014-05-04 01:13:23 【问题描述】:我有以下疑问:
select * from my_table
where (col1, col2) in ( (1000,1), (2000,2) )
我在 col1、col2 和 col1 和 col2 上一起定义了索引。如果我对其进行解释,我会看到 mysql 找不到要使用的可用索引。有趣的是,如果我在 IN 子句中只放一对,解释会找到所有索引。
试力指数,无济于事
任何想法,我怎样才能让mysql识别索引?
【问题讨论】:
将实际的表/索引定义发布到问题本身中。 【参考方案1】:您需要MySql 5.7.3 或以上版本 早期版本未实现对行构造函数表达式的优化 详情请点击此链接:https://dev.mysql.com/doc/refman/5.7/en/range-optimization.html#row-constructor-range-optimization
8.2.1.3.4 行构造函数表达式的范围优化
从 MySQL 5.7.3 开始,优化器能够将范围扫描访问方法应用于这种形式的查询:
SELECT ... FROM t1 WHERE (col_1, col_2) IN (('a', 'b'), ('c', 'd'));
以前,要使用范围扫描,查询必须写成:
SELECT ... FROM t1 WHERE ( col_1 = 'a' AND col_2 = 'b' ) 或 (col_1 = 'c' AND col_2 = 'd');
注意:行构造函数是以下形式的表达式:( value1, value2, ... ,valueN)
或 ROW( val1, val2, ..., valN)
。
【讨论】:
这是正确的方法,但由于我无法升级版本,我设法通过仅在其中一列上添加 where in 的解决方法来解决这个问题......详情见我的回答。【参考方案2】:我设法在不升级 mysql 版本的情况下解决了这个问题,方法是仅在其中一列上添加额外的 where in 条件:
select * from my_table
where (col1, col2) in ( (1000,1), (2000,2) )
and col1 in (1000,2000)
这样,优化器将在 col1 上找到索引,并按它进行搜索,这对我来说已经完成了这项工作。
【讨论】:
【参考方案3】:我不知道这一点;所以首先尝试(小提琴http://sqlfiddle.com/#!2/f88bb/2),是的,它是正确的;对于多列 IN 子句,它使用 full table scan
而不是使用可用的索引。
经过一番搜索发现这是MySQL中的一个BUG,目标是在MySQL 6.x
中发布或修复。
查看此处获取完整信息Multi column IN does not use index
所以现在您可以将查询转换为使用单个 IN 子句,以便它识别索引;喜欢
select * from my_table
where col1 in ( 1000,2000) and col2 in (1,2)
创建 BUG/优化请求的人已在此处解释(或)给出的复制步骤
Multi-Column IN clause – Unexpected MySQL Issue
【讨论】:
以上是关于Mysql 不使用包含两列的索引的主要内容,如果未能解决你的问题,请参考以下文章