索引

2014-11-06 31 views
0

MariaDB的SQL性能问题,我们有如下的MariaDB的MariaDB的,5.5.37-1.el7_0.x86_64查找IP地理位置的表:索引

CREATE TABLE ip2location_db24
id INT(11)NOT NULL AUTO_INCREMENT,
ip_from INT(10)无符号DEFAULT NULL,
ip_to INT(10)无符号DEFAULT NULL,
country_code炭(2)COLLATE utf8_bin DEFA ULT NULL,
country_name VARCHAR(64)COLLATE utf8_bin DEFAULT NULL,
region_name VARCHAR(128)COLLATE utf8_bin DEFAULT NULL,
city_name VARCHAR(128)COLLATE utf8_bin DEFAULT NULL,
latitude双DEFAULT NULL,
longitude双DEFAULT NULL,
zip_code VARCHAR(30)COLLATE utf8_bin DEFAULT NULL,
time_zone VARCHAR(8)COLLATE utf8_bin DEFAULT NULL,
isp VARCHAR(255)COLLATE utf8_bin DEFAULT NULL,
domain VARCHAR(128)COLLATE utf8_bin DEFAULT NULL,
net_speed VARCHAR(8)COLLATE utf8_bin DEFAULT NULL,
idd_code VARCHAR(5)COLLATE utf8_bin DEFAULT NULL,
area_code VARCHAR (30)COLLATE utf8_bin DEFAULT NULL,
weather_station_code VARCHAR(10)COLLATE utf8_bin DEFAULT NULL,
weather_station_name VARCHAR(128)COLLATE utf8_bin DEFAULT NULL,
mcc VARCHAR(256)COLLATE utf8_bin DEFA ULT NULL,
mnc VARCHAR(256)COLLATE utf8_bin DEFAULT NULL,
mobile_brand VARCHAR(128)COLLATE utf8_bin DEFAULT NULL,
elevation INT(10)DEFAULT NULL,
usage_type VARCHAR(11)COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY(id),
KEY idx_ip_fromip_from),
KEY idx_latitudelatitude),
KEY idx_longitudelongitude),
KEY idx_ip_from_to_2ip_toip_from
)ENGINE = InnoDB的AUTO_INCREMENT = 9541211默认字符集= UTF8 COLLATE = utf8_bin

ip_from和ip_to列定义的开始和每地理结束边界位置。

我们在此表中有大约1000万条记录。

当查询指定的IP地理位置,我们发现服务器遭受用下面的SQL一个严重的性能问题:从ip2location_db24其中ip_to> = 1908980838和ip_from < = 1908980838极限

SELECT * 1; *************************** 1. row ******************* ********
ID:5475739
ip_from:1908932608
ip_to:1909063679
COUNTRY_CODE:CN
COUNTRY_NAME:中国
REGION_NAME:山西
CITY_NAME:太原
纬度:37.86944
经度:112.56028
zip_code: -
TIME_ZONE:+08:00
ISP:中国联通陕西省网络
域:CHINAUNICOM.COM
net_speed:DSL
idd_code:86
AREA_CODE:0351
weather_station_code:CHXX0129
weather_station_name:太原
mcc:460
mnc:01/06
mobile_brand:CHINA UNICOM
elevation:787
usage_type:ISP/MOB
1行集(15.08秒)

然而,使用以下等效SQL,其非常快速查询时。

SELECT * FROM ip2location_db24其中ip_from < = 1908980838为了通过ip_from DESC LIMIT 1 \ G变 ************************ *** 1.行***************************
ID:5475739
ip_from:1908932608
ip_to:1909063679
国家代码:CN
country_name:CHINA
region_name:SHANXI
CITY_NAME:太原
纬度:37.86944
经度:112.56028
ZIP_CODE: -
TIME_ZONE:+08:00
ISP:中国联通陕西省网络
域:中国联通。COM
net_speed:DSL
idd_code:86
AREA_CODE:0351
weather_station_code:CHXX0129
weather_station_name:太原
MCC:460
MNC:01/06
mobile_brand:中国联通
海拔:787
usage_type:ISP/MOB
set in set(0.00 sec)

问题是,当我们检查执行计划时,两个查询对ip_from列的索引使用相同的范围扫描。但是这两个SQL的表现还远未结束。任何人有这个理由的任何想法?

为了提供更多信息,我们还测试了其输出列完全被索引覆盖的查询。

MariaDB的[ip2location]选择ip_from,ip_to从ip2location_db24其中ip_to> = 1908980838和ip_from < = 1908980838极限1;
+ ------------ + ------------ +
| ip_from | ip_to |
+ ------------ + ------------ +
| 1908932608 | 1909063679 |
+ ------------ + ------------ +
1行集(0.01秒)

注上面的查询SQL是闪电般的。但查询不包括在索引任何额外的列时,它需要的时间不可思议长期:

> MariaDB的[ip2location]选择ip_from,ip_to,从ip2location_db24其中ip_to> = 1908980838和ip_from < = 1908980838极限COUNTRY_CODE 1;
+ ------------ + ------------ + -------------- +
| ip_from | ip_to | country_code |
+ ------------ + ------------ + -------------- +
| 1908932608 | 1909063679 | CN |
+ ------------ + ------------ + -------------- +
1 row in set (10.15秒)

回答

0
select * from ip2location_db24 where ip_to >=1908980838 and ip_from <=1908980838 limit 1; 

缓慢的,因为比较两列。

select * from ip2location_db24 where ip_from <=1908980838 order by ip_from desc limit 1 

快速因为只有一个索引列进行比较。

-1

尝试force index如MariaDB的手动部Forcing an index描述:

select ip_from,ip_to,country_code 
from ip2location_db24 force index (idx_ip_from_to_2) 
where ip_to >=1908980838 and ip_from <=1908980838 
limit 1;