楼主: grantguan

MySQL 在between 上的索引问题

[复制链接]
论坛徽章:
27
优秀写手
日期:2013-12-18 09:29:09ITPUB季度 技术新星
日期:2012-08-15 14:50:13嫦娥
日期:2013-03-04 09:47:05数据库板块每日发贴之星
日期:2011-09-08 01:01:01数据库板块每日发贴之星
日期:2011-09-11 01:01:01数据库板块每日发贴之星
日期:2011-09-10 01:01:02数据库板块每日发贴之星
日期:2011-09-09 01:01:01ITPUB十周年纪念徽章
日期:2011-11-01 16:26:59ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:422013年新春福章
日期:2013-03-04 09:50:49
11#
发表于 2013-7-24 12:00 | 只看该作者
个人觉得你的表建立不是很恰当.从你的sql写法就可以看出来

使用道具 举报

回复
论坛徽章:
27
优秀写手
日期:2013-12-18 09:29:09ITPUB季度 技术新星
日期:2012-08-15 14:50:13嫦娥
日期:2013-03-04 09:47:05数据库板块每日发贴之星
日期:2011-09-08 01:01:01数据库板块每日发贴之星
日期:2011-09-11 01:01:01数据库板块每日发贴之星
日期:2011-09-10 01:01:02数据库板块每日发贴之星
日期:2011-09-09 01:01:01ITPUB十周年纪念徽章
日期:2011-11-01 16:26:59ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:422013年新春福章
日期:2013-03-04 09:50:49
12#
发表于 2013-7-24 12:03 | 只看该作者
grantguan 发表于 2013-7-24 12:28
这个需求正常,一个ip table,输入随便一个ip,定位这个ip 来自哪个国家,ip 表存放数据start_ip,end_ip,转 ...

where 3533 between ip.number_start and ip.number_end;这种写法很少见到,换成  ip.number_start < 3533  and ip.number_end >3533 ; 试试看呢?

使用道具 举报

回复
论坛徽章:
15
生肖徽章2007版:猪
日期:2009-03-11 15:09:30优秀写手
日期:2013-12-18 09:29:11比亚迪
日期:2013-08-28 12:44:17复活蛋
日期:2013-06-19 15:03:392013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15奥运会纪念徽章:手球
日期:2012-08-28 17:54:31奥运会纪念徽章:柔道
日期:2012-08-14 16:26:23咸鸭蛋
日期:2012-08-14 16:26:232010广州亚运会纪念徽章:射击
日期:2012-08-14 16:26:23
13#
 楼主| 发表于 2013-7-24 12:07 | 只看该作者
mchdba 发表于 2013-7-24 12:03
where 3533 between ip.number_start and ip.number_end;这种写法很少见到,换成  ip.number_start < 353 ...

这个表是IP的标准库,从Maxmind 购买的,
最开始采用ip.number_start <= 3533 and ip.number_end>=3533的写法,也是一样

使用道具 举报

回复
论坛徽章:
27
优秀写手
日期:2013-12-18 09:29:09ITPUB季度 技术新星
日期:2012-08-15 14:50:13嫦娥
日期:2013-03-04 09:47:05数据库板块每日发贴之星
日期:2011-09-08 01:01:01数据库板块每日发贴之星
日期:2011-09-11 01:01:01数据库板块每日发贴之星
日期:2011-09-10 01:01:02数据库板块每日发贴之星
日期:2011-09-09 01:01:01ITPUB十周年纪念徽章
日期:2011-11-01 16:26:59ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:422013年新春福章
日期:2013-03-04 09:50:49
14#
发表于 2013-7-24 12:24 | 只看该作者
grantguan 发表于 2013-7-24 13:07
这个表是IP的标准库,从Maxmind 购买的,
最开始采用ip.number_start =3533的写法,也是一样

嗯,明白了,今天长知识了,还可以那样写 between and,挺好的.

使用道具 举报

回复
论坛徽章:
15
生肖徽章2007版:猪
日期:2009-03-11 15:09:30优秀写手
日期:2013-12-18 09:29:11比亚迪
日期:2013-08-28 12:44:17复活蛋
日期:2013-06-19 15:03:392013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15奥运会纪念徽章:手球
日期:2012-08-28 17:54:31奥运会纪念徽章:柔道
日期:2012-08-14 16:26:23咸鸭蛋
日期:2012-08-14 16:26:232010广州亚运会纪念徽章:射击
日期:2012-08-14 16:26:23
15#
 楼主| 发表于 2013-7-24 12:25 | 只看该作者
看样子和参数值处于索引中的位置关系很大,3百万的表到150万就开始full table scan了,闲来无事,做一个测试:


50万的时候还走索引


120万的时候还在走索引


到150万的时候,彻底full scan 了


砖家们,求解决方案

使用道具 举报

回复
论坛徽章:
52
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:32:552012新春纪念徽章
日期:2012-02-07 09:59:35
16#
发表于 2013-7-24 16:44 | 只看该作者
CREATE TABLE `ip` (
  `id` bigint(20) NOT NULL,
  `address_start` varchar(16) NOT NULL,
  `address_end` varchar(16) NOT NULL,
  `number_start` bigint(20) NOT NULL,
  `number_end` bigint(20) NOT NULL,
  `country_code` varchar(3) NOT NULL,
  `city_id` bigint(20) NOT NULL,
  PRIMARY KEY (`number_start`,`number_end`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

1.你的字符串类型 应该设计为 整型,这样性能更好
2.你的数据分布也有关系;
3.你的查询范围跨度很大,那么则可能导致无法走索引

使用道具 举报

回复
论坛徽章:
15
生肖徽章2007版:猪
日期:2009-03-11 15:09:30优秀写手
日期:2013-12-18 09:29:11比亚迪
日期:2013-08-28 12:44:17复活蛋
日期:2013-06-19 15:03:392013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15奥运会纪念徽章:手球
日期:2012-08-28 17:54:31奥运会纪念徽章:柔道
日期:2012-08-14 16:26:23咸鸭蛋
日期:2012-08-14 16:26:232010广州亚运会纪念徽章:射击
日期:2012-08-14 16:26:23
17#
 楼主| 发表于 2013-7-24 17:03 | 只看该作者
jinguanding 发表于 2013-7-24 16:44
CREATE TABLE `ip` (
  `id` bigint(20) NOT NULL,
  `address_start` varchar(16) NOT NULL,

反复测试得到终极解决方案,创建2个index
index1 on(number_start,number_end)
index2 on(number_end,number_start)
同样的column但是不一样的顺序,这样测试下来无论参数值在哪一个范围,都可以避免full scan, 最慢也是0.2sec,快了几倍,算是交差了,
真是奇葩,还好这是一个静态表。

使用道具 举报

回复
论坛徽章:
27
优秀写手
日期:2013-12-18 09:29:09ITPUB季度 技术新星
日期:2012-08-15 14:50:13嫦娥
日期:2013-03-04 09:47:05数据库板块每日发贴之星
日期:2011-09-08 01:01:01数据库板块每日发贴之星
日期:2011-09-11 01:01:01数据库板块每日发贴之星
日期:2011-09-10 01:01:02数据库板块每日发贴之星
日期:2011-09-09 01:01:01ITPUB十周年纪念徽章
日期:2011-11-01 16:26:59ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:422013年新春福章
日期:2013-03-04 09:50:49
18#
发表于 2013-7-24 17:14 | 只看该作者
grantguan 发表于 2013-7-24 18:03
反复测试得到终极解决方案,创建2个index
index1 on(number_start,number_end)
index2 on(number_end,n ...

这个方案值得借鉴,谢谢分享.

使用道具 举报

回复
论坛徽章:
52
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:32:552012新春纪念徽章
日期:2012-02-07 09:59:35
19#
发表于 2013-7-24 17:38 | 只看该作者
grantguan 发表于 2013-7-24 17:03
反复测试得到终极解决方案,创建2个index
index1 on(number_start,number_end)
index2 on(number_end,n ...

但是你这样成本上去了~~ INSERT 就可怕了

使用道具 举报

回复
论坛徽章:
15
生肖徽章2007版:猪
日期:2009-03-11 15:09:30优秀写手
日期:2013-12-18 09:29:11比亚迪
日期:2013-08-28 12:44:17复活蛋
日期:2013-06-19 15:03:392013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15奥运会纪念徽章:手球
日期:2012-08-28 17:54:31奥运会纪念徽章:柔道
日期:2012-08-14 16:26:23咸鸭蛋
日期:2012-08-14 16:26:232010广州亚运会纪念徽章:射击
日期:2012-08-14 16:26:23
20#
 楼主| 发表于 2013-7-24 17:59 | 只看该作者
jinguanding 发表于 2013-7-24 17:38
但是你这样成本上去了~~ INSERT 就可怕了

静态表,只有select。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表