是否可以在最左边的多重索引上按范围进行选择?

发布于 2024-10-06 06:27:20 字数 945 浏览 7 评论 0原文

我在 (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 do
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

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

将军与妓 2024-10-13 06:27:20
  1. 不,不是。
  2. 不,你做的一切都是正确的

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>=500k2 IN(...) AND k2>2000 (我不知道为什么你这里需要> 2000,因为你可以手动比较它,然后添加到IN()),你也可以尝试创建索引k2 (如果 k2 部分返回较少数量的记录)。

  1. No it is not.
  2. No, you're doing everything right

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:

k1>=500 AND k2 IN(...) AND k2>2000

Depending of which part returns fewer records, either k1>=500 or k2 IN(...) AND k2>2000 (I'm not sure why do you need > 2000 here, due to you can compare it manually, before add to IN()), you could also try to create index k2 (if k2 part returns less amount of records).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文