使用索引优化mysql查询

时间:2011-12-25 18:52:08

标签: mysql optimization indexing b-tree

我对此查询有疑问:

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时,我得到这样的结果:{{3}这些NULL是否意味着查询没有使用索引?索引是一个BTREE所以我认为这应该运行得更快。

你能帮我解决这个问题吗?如果还有其他任何信息,请告诉我。

编辑:我有关于suspects.postalcode,postal_codes.start,postal_codes.end,postal_codes.user_id的索引。

基本上我想要实现的目标:我有一个表,其中每个用户ID分配了多个邮政编码范围,所以它看起来像:

user_id | start | end

我有一个嫌疑人表,每个嫌疑人都有一个地址(包含邮政编码),所以在这个查询中我试图获得邮政编码范围 - 开始和结束以及该范围内的城市名称。 / p>

希望这有帮助。

6 个答案:

答案 0 :(得分:2)

每当使用左连接时,将拾取第一个表的所有记录,而不是基于索引的选择。我建议使用内连接。类似于下面的查询。

select distinct 
  s.city, 
  pc.start, 
  pc.end 
from postal_codes pc, suspect s 
where 
  s.postalcode between (select pc1.start, pc1.end from postal_code pc1 where pc1.user_id = "username" ) 
  and pc.user_id = "username"
order by pc.start

答案 1 :(得分:0)

它只使用一个索引,而不是连接中涉及的字段。尝试为开始和结束字段创建索引,或使用> =和< =而不是BETWEEN

答案 2 :(得分:0)

不是100%肯定,但this可能是相关的:

  

有时MySQL不使用索引,即使有索引也是如此。发生这种情况的一种情况是,优化器估计使用索引将需要MySQL访问表中非常大比例的行。 (在这种情况下,表扫描可能会快得多,因为它需要更少的搜索。)但是,如果这样的查询使用LIMIT只检索一些行,MySQL无论如何都使用索引,因为它可以更快地找到在结果中返回的几行。

所以尝试使用LIMIT进行测试,如果它使用了索引,那么就找到了原因。

答案 3 :(得分:0)

我不得不说我对你的表命名约定感到有些困惑,我希望“suspect”表有一个user_id而不是postal_code,但你必须有你的理由。如果您原样保留此查询,则可以在postal_code(star,end)上添加索引以避免完整的表扫描。

答案 4 :(得分:0)

我认为您可以重新构建您的查询,如下所示,

SELECT DISTINCT s.city, pc1.start, pc1.end FROM 
(SELECT pc.start and pc.end from postal_codes pc where pc.user_id = "username") as pc1,    Suspect s
WHERE s.postalcode BETWEEN pc1.start, pc1.end ORDER BY pc1.start

由于左连接和你的条件,你的查询没有在s表上获取索引。在表中包含索引并不一定意味着它将在所有查询中使用。

答案 5 :(得分:0)

尝试FORCE INDEX