我在m_idx
上有一个索引(k1,k2,k3)
如果我这样做
SELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1=500 AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
OR
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上使用范围:
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
在所有情况下,EXPLAIN都说使用的密钥是m_idx
但我认为在第三种情况下m_idx
没有使用它(我也只在k1上有一个索引)。
否则我不明白为什么它读的行超过1000行
我希望扫描满足要从表中读取的条件的m_idx
索引和ONLY the first 1000
行。
但实际上我认为对于第三种情况,它会扫描索引,并且从tb读取满足k1条件的那些行,并且在从tb读取行之后检查k2和k3条件。
我使用:MySql和MyISAM,WINDOWS 7 64,tb有1 mil行;
所以我的问题是:
是否可以在最左边的多指数上选择范围?
OR
我做错了什么?
谢谢。
答案 0 :(得分:0)
http://dev.mysql.com/doc/refman/5.1/en/range-optimization.html(“7.3.1.3.2。多部分索引的范围访问方法”部分)
因此,您无法帮助优化程序更快地执行此查询。
并且避免使用FORCE INDEX
,因为优化器更了解要使用的索引。
此外:
k1>=500 AND k2 IN(...) AND k2>2000
根据哪个部分返回的记录较少,k1>=500
或k2 IN(...) AND k2>2000
(我不知道您为什么需要> 2000
,因为您可以在添加之前手动对其进行比较到IN()
),您还可以尝试创建索引k2
(如果k2
部分返回的记录数量较少)。