MySQL BETWEEN查询未使用索引

马丁·穆勒(MartinMüller):

我在表中有geoip数据,network_start_ip并且network_end_ipvarbinary(16)带有INET6_ATON(ip_start/end)as值结果的列其他2列是经度和纬度。

CREATE TABLE `ipblocks` (
 `network_start_ip` varbinary(16) NOT NULL,
 `network_last_ip` varbinary(16) NOT NULL,
 `latitude` double NOT NULL,
 `longitude` double NOT NULL,
 KEY `network_start_ip` (`network_start_ip`),
 KEY `network_last_ip` (`network_last_ip`),
 KEY `idx_range` (`network_start_ip`,`network_last_ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

如您所见,我已经创建了3个用于测试的索引。为什么我的查询(非常简单)

SELECT 
    latitude, longitude
FROM
    ipblocks b
WHERE
    INET6_ATON('82.207.219.33') BETWEEN b.network_start_ip AND b.network_last_ip

不使用任何这些索引?

EXPLAIN的结果

该查询大约需要3秒钟的时间,太长了,无法在生产中使用它。

马丁·穆勒(MartinMüller):

感谢Gordon Linoff,我找到了针对我的问题的最佳查询。

SELECT b.* FROM 
  (SELECT b.* FROM ipblocks b WHERE b.network_start_ip <= INET6_ATON('82.207.219.33') 
                              ORDER BY b.network_start_ip DESC LIMIT 1 ) 
b WHERE INET6_ATON('82.207.219.33') <= network_last_ip

现在,我们选择内部查询的块INET6_ATON(82.207.219.33),但对它们进行降序排列,使我们能够LIMIT 1再次使用它们

现在,查询响应时间为.002到.004秒。大!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章