我对此查询有疑问:
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>
希望这有帮助。
答案 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。