为什么MySQL在范围查询中不使用复合键?

时间:2012-12-11 11:06:24

标签: mysql composite-key composite-primary-key

我已经检查了很多其他SO帖子和MySQL文档,但似乎无法得到关于为什么没有使用索引的答案,以及如何强制使用它 - 我可以看到许多其他人有类似的问题,但无法找到解决方案。

表格如下所示

CREATE TABLE `countries_ip` (
`ipfrom` INT(10) UNSIGNED ZEROFILL NOT NULL,
`ipto` INT(10) UNSIGNED ZEROFILL NOT NULL,
`countrySHORT` CHAR(2) NULL DEFAULT NULL,
`country_id` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`ipfrom`, `ipto`, `country_id`),
INDEX `from_to_index` (`ipfrom`, `ipto`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

不确定为什么“from_to_index”存在 - 对我来说似乎是多余的。但无论如何,EXPLAIN查询看起来像这样

EXPLAIN SELECT *
        FROM track_report t, countries_ip ip
        WHERE t.ip BETWEEN ip.ipfrom AND ip.ipto

,EXPLAIN的结果如下:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  t   ALL getwebmaster    NULL    NULL    NULL    36291   
1   SIMPLE  ip  ALL PRIMARY,from_to_index   NULL    NULL    NULL    153914  Range checked for each record (index map: 0x3)

如您所见,countries_ip表中的PRIMARY KEY未被使用,因此查询需要很长时间(countries_ip有超过150k的记录)

我可能遗漏了一些简单的东西,但是对于如何优化此查询,我们将不胜感激。提前谢谢。

1 个答案:

答案 0 :(得分:1)

可能有助于在track_report.ip上定义索引。请参阅SQL Fiddle

我修改了where子句来进行显式比较,现在它使用了from_to_index。

SELECT ip
FROM track_report t, countries_ip ip
where t.ip >= ip.ipfrom and t.ip <= ip.ipto

请参阅SQL Fiddle