使用索引优化mysql查询
我对这个查询有一个问题:
SELECT DISTINCT s.city, pc.start, pc.end
FROM postal_codes pc LEFT JOIN suspects s ON (s.postalcode BETWEEN pc.start AND pc.end)
WHERE pc.user_id = "username"
ORDER BY pc.start
可疑表有大约 340 000 个条目,在邮政编码上有一个索引,我有几个用户,但是这个单独的查询大约需要 0.5 秒,当我用解释运行这个 SQL 时,我得到这样的结果:http://my.jetscreenshot.com/7536/20111225-myhj-41kb.jpg - 这些 NULL 是否意味着查询未使用索引?该索引是一个 BTREE,所以我认为它应该运行得更快一点。
你能帮我解决这个问题吗?如果需要任何其他信息,请告诉我。
编辑:我在 Suspects.postalcode、postal_codes.start、postal_codes.end、postal_codes.user_id 上有索引。
基本上我想要实现的目标是:我有一个表,其中每个用户 ID 都分配了多个邮政编码范围,所以它看起来像:
user_id | start | end
比我有一个嫌疑人表,其中每个嫌疑人都有一个地址(其中包含邮政编码),所以在这个查询我试图获取邮政编码范围 - 开始和结束以及该范围内的城市名称。
希望这有帮助。
I have a problem with this query:
SELECT DISTINCT s.city, pc.start, pc.end
FROM postal_codes pc LEFT JOIN suspects s ON (s.postalcode BETWEEN pc.start AND pc.end)
WHERE pc.user_id = "username"
ORDER BY pc.start
Suspect table has about 340 000 entries, there is a index on postalcode, I have several users, but this individual query takes about 0.5s, when I run this SQL with explain, I get something like this: http://my.jetscreenshot.com/7536/20111225-myhj-41kb.jpg - does these NULLs mean that the query isn't using index? The index is a BTREE so I think this should run a little faster.
Can you please help me with this? If there are any other informations needed just let me know.
Edit: I have indexes on suspects.postalcode, postal_codes.start, postal_codes.end, postal_codes.user_id.
Basically what I'm trying to achieve: I have a table where each user ID has multiple postalcode ranges assigned, so it looks like:
user_id | start | end
Than I have a table of suspects where each suspect has an address (which contains a postalcode), so in this query I'm trying to get postalcode range - start and end and also name of the city in this range.
Hope this helps.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
每当使用左连接时,都会选取第一个表的所有记录,而不是基于索引进行选择。我建议使用内部联接。就像下面的查询一样。
Whenever left join is used all the records of the first table are picked up rather than the selection on the basis of index. I would suggest to using an inner join. Something like in the below query.
它仅使用一个索引,而不是连接中涉及的字段。尝试为开始和结束字段创建索引,或使用 >= 和 <= 而不是 BETWEEN
It's using only one index, and not for the fields involved in the join. Try creating an index for the start and end fields, or using >= and <= instead of BETWEEN
不是100%确定,但是这可能是相关的:
因此,尝试使用
LIMIT
进行测试,如果它使用索引,那么您就找到了原因。Not 100% sure, but this might be relevant:
So try testing with
LIMIT
, and if it uses the index then, you found your cause.我不得不说我对你的表命名约定有点困惑,我希望“可疑”表有一个 user_id 而不是 postal_code,但你必须有你的理由。如果您要保持此查询不变,则可以在 postal_code (star,end) 上添加索引以避免完整的表扫描。
I have to say I'm a little confused by your table naming convention, I would expect the "suspect" table to have a user_id not the postal_code, but you must have your reasons. If you were to leave this query as it is, you can add an index on postal_code (star,end) to avoid the complete table scan.
我认为您可以像下面这样重构您的查询,
由于左连接和您的之间条件,您的查询没有选取 s 表上的索引。表中拥有索引并不一定意味着它将在所有查询中使用。
I think you can restructure your query like following,
your query is not picking up the index on s table because of left join and your between condition. Having an Index in your table doesn't necessarily mean that it will be used in all the queries.
尝试强制索引。
Try FORCE INDEX.