是否可以在最左边的多重索引上按范围进行选择?
我在 (k1,k2,k3)
上有一个索引 m_idx
如果我这样做的话从 tb FORCE INDEX (m_idx) 中选择 c1,c2,c3...,其中 k1=500 AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
或
SELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1 IN (500,1000,1500 ...) AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
Handler_read_next = 999
但是如果我尝试在 k1 上使用范围:从 tb FORCE INDEX (m_idx) 中选择 c1,c2,c3...,其中 k1>=500 AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
Handler_read_next = 58035
在所有情况下,EXPLAIN 都表示使用的密钥是 m_idx
但我认为在第三种情况 m_idx
中它没有被使用(我也只在 k1 上有一个索引)。
否则我不明白为什么它读取超过 1000 行。
我期望扫描 m_idx
索引,并且仅扫描满足从表中读取条件的前 1000 行
行。
但实际上我认为对于第三种情况,它会扫描索引,并从 tb 中读取满足 k1 条件的那些行,并在从 tb 读取行后检查 k2 和 k3 条件。
我使用:MySql 和 MyISAM,WINDOWS 7 64,tb 有 1 百万行;
所以我的问题是:
是否可以在最左边的多重索引上按范围进行选择?
或
我还做错了什么吗?
谢谢。
I have an index m_idx
on (k1,k2,k3)
If I doSELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1=500 AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
ORSELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1 IN (500,1000,1500 ...) AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
Handler_read_next = 999
BUT if I try to use a range on k1:SELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1>=500 AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
Handler_read_next = 58035
In all cases EXPLAIN says that the key used is m_idx
But I think that in the third case m_idx
it's not used (I also have an index only on k1).
Otherwise I don't understand why it'is reading more than 1000 rows.
I was expecting to scan m_idx
index, and ONLY the first 1000
rows that meet the conditions to be read from table.
But in fact I think that for the third case it scans the index and those rows who meet k1 condition are read from the tb and k2 and k3 conditions are checked after the rows are read from tb.
I use: MySql with MyISAM, WINDOWS 7 64, the tb has 1 mil rows;
So my questions are:
Is it possible to select by range on leftmost multiple-index?
OR
I'm doing something else wrong?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
http://dev.mysql .com/doc/refman/5.1/en/range-optimization.html(“7.3.1.3.2.多部分索引的范围访问方法”部分)
因此您无法帮助优化器更快地执行此查询。
并避免使用
FORCE INDEX
,因为优化器更清楚要使用什么索引。另外:
根据哪个部分返回较少的记录,
k1>=500
或k2 IN(...) AND k2>2000
(我不知道为什么你这里需要> 2000
,因为你可以手动比较它,然后添加到IN()
),你也可以尝试创建索引k2
(如果k2
部分返回较少数量的记录)。http://dev.mysql.com/doc/refman/5.1/en/range-optimization.html ("7.3.1.3.2. The Range Access Method for Multiple-Part Indexes" part)
So you cannot help optimizer to perform this query faster.
And avoid using
FORCE INDEX
, since optimizer knows better what index to use.Also:
Depending of which part returns fewer records, either
k1>=500
ork2 IN(...) AND k2>2000
(I'm not sure why do you need> 2000
here, due to you can compare it manually, before add toIN()
), you could also try to create indexk2
(ifk2
part returns less amount of records).