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
),
KEYidx_ip_from
(ip_from
),
KEYidx_latitude
(latitude
),
KEYidx_longitude
(longitude
),
KEYidx_ip_from_to_2
(ip_to
,ip_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秒)