首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在MySQL中使用索引

问在MySQL中使用索引
EN

Stack Overflow用户
提问于 2013-10-18 07:40:08
回答 2查看 54关注 0票数 0

奇怪的事发生了。有谁能解释一下。我有张桌子。

代码语言:javascript
复制
CREATE TABLE "country_ip" (
  "begin_ip" varchar(15) NOT NULL,
  "end_ip" varchar(15) NOT NULL,
  "begin_ip_long" int(10) unsigned NOT NULL,
  "end_ip_long" int(10) unsigned NOT NULL,
  "id" char(2) NOT NULL,
  "label" varchar(50) NOT NULL,
  KEY "begin_ip_long" ("begin_ip_long","end_ip_long"),
  KEY "end_ip_long" ("end_ip_long")
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

有大约15万条记录。下一个查询有很大的时间差。

代码语言:javascript
复制
0.06329400 | SELECT * FROM `country_ip` WHERE '1405662435' BETWEEN `begin_ip_long` AND `end_ip_long` LIMIT 1
0.06214600 | SELECT * FROM `country_ip` USE INDEX (begin_ip_long, end_ip_long) WHERE 1405662435 BETWEEN `begin_ip_long` AND `end_ip_long` LIMIT 1
0.00008400 | SELECT * FROM `country_ip` USE INDEX (end_ip_long) WHERE 1405662435 BETWEEN `begin_ip_long` AND `end_ip_long` LIMIT 1

有人能解释一下为什么会发生这种事吗?我的意思是为什么只有使用索引(end_ip_long)才有帮助,而使用USE INDEX (begin_ip_long)或USE INDEX (begin_ip_long,end_ip_long)则没有效果。谢谢。

EN

回答 2

Stack Overflow用户

发布于 2013-10-18 07:49:11

可能是因为索引(end_ip_long)比(begin_ip_long, end_ip_long)小,它适合内存,而且一列足够有选择性。而较大的索引可能需要从磁盘读取。

票数 1
EN

Stack Overflow用户

发布于 2013-10-18 08:01:07

既然您可以让单列(END_IP_LONG)索引快速工作,那么为什么不只是索引&在一列上搜索呢?

我可能会使用BEGIN_IP_LONG搜索第一条记录,其中指定的IP是>= country.BEGIN_IP_LONG,按IP降序,限制1。这应该是检索“地板”条目,然后您所需要做的就是检查指定的IP是否超出了该国的END_IP_LONG。

这将正确地完成查找,只使用单列索引。(所有这些假设范围不重叠,考虑到您指定的结构,我认为这是正确的。)

正如其他人所建议的那样,研究MySQL的计划(或许还包括重建统计数据)是值得的--但从技术上讲,不重叠的范围查找在技术上应该可以仅在单个界限上使用索引。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19444189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档