【问题标题】:MariaDB SQL performance issue with index索引的 MariaDB SQL 性能问题
【发布时间】:2014-11-06 06:52:56
【问题描述】:

我们有一张表用于在 MariaDB mariadb-5.5.37-1.el7_0.x86_64 上查找 IP 地理位置,如下所示:

创建表ip2location_db24 (
id int(11) NOT NULL AUTO_INCREMENT,
ip_from int(10) unsigned DEFAULT NULL,
ip_to int(10) unsigned DEFAULT NULL ,
country_code char(2) 整理 utf8_bin 默认为 NULL,
country_name varchar(64) 整理 utf8_bin 默认为 NULL,
region_name varchar(128) 整理 utf8_bin 默认为 NULL,
@ 987654328@ varchar(128) 整理 utf8_bin 默认空值,
latitude 双默认空值,
longitude 双倍默认空值,
zip_code varchar(30) 整理 utf8_bin 默认空值,
@ 987654332@ varchar(8) 整理 utf8_bin 默认空值,
isp varchar(255) 整理 utf8_bin 默认空值,
domain varchar(128) 整理 utf8_bin 默认空值,
net_speed varchar( ) 整理 utf8_bin 默认空值,
idd_code varchar(5) 整理 utf8_bin 默认空值,
area_code varchar(30) 整理 utf8_bin 默认空值,
weather_station_code varchar(10) 整理 utf8_bin 默认空值,
weather_station_name varchar(128) 整理 utf8_bin 默认为 NULL,
@98 7654340@ varchar(256) 整理 utf8_bin 默认空值,
mnc varchar(256) 整理 utf8_bin 默认空值,
mobile_brand varchar(128) 整理 utf8_bin 默认空值,
elevation int( ) 默认空值,
usage_type varchar(11) 整理 utf8_bin 默认空值,
主键 (id),
idx_ip_from (ip_from),
idx_latitude (latitude),
idx_longitude (longitude),
idx_ip_from_to_2 (ip_to,ip_from)
) ENGINE=InnoDB AUTO_INCREMENT=9541211 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

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

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

在查询给定 IP 的地理位置时,我们发现服务器遇到以下 SQL 的严重性能问题:

select * from ip2location_db24 where ip_to >=1908980838 and ip_from 编号:5475739
ip_from: 1908932608
ip_to: 1909063679
国家代码:CN
国家名称:中国
地区名称:山西
城市名称:太原
纬度:37.86944
经度:112.56028
邮编:-
时区:+08:00
isp:中国联通陕西省网络
域名:中国联通
网络速度:DSL
idd_code: 86
区号:0351
气象站代码:CHXX0129
气象站名称:太原
mcc: 460
跨国公司:01/06
mobile_brand: 中国联通
海拔:787
使用类型:ISP/MOB
一组中的 1 行(15.08 秒)

但是,使用以下等效 SQL 进行查询时,速度非常快。

select * from ip2location_db24 where ip_from 编号:5475739
ip_from: 1908932608
ip_to: 1909063679
国家代码:CN
国家名称:中国
地区名称:山西
城市名称:太原
纬度:37.86944
经度:112.56028
邮编:-
时区:+08:00
isp:中国联通陕西省网络
域名:中国联通
网络速度:DSL
idd_code: 86
区号:0351
气象站代码:CHXX0129
气象站名称:太原
mcc: 460
跨国公司:01/06
mobile_brand: 中国联通
海拔:787
使用类型:ISP/MOB
一组中的 1 行(0.00 秒)

问题是,当我们检查执行计划时,两个查询都对 ip_from 列的索引使用相同的范围扫描。但这两个 SQL 的性能还差得很远。有人知道这是什么原因吗?

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

MariaDB [ip2location] select ip_from,ip_to from ip2location_db24 where ip_to >=1908980838 and ip_from +------------+------------+
| ip_来自 | ip_to |
+------------+------------+
| 1908932608 | 1909063679 |
+------------+------------+
一组中的 1 行(0.01 秒)

请注意,上面的查询 SQL 快如闪电。但是在查询任何没有被索引覆盖的附加列时,它会花费令人难以置信的长时间:

> MariaDB [ip2location] select ip_from,ip_to,country_code from ip2location_db24 where ip_to >=1908980838 and ip_from +------------+------------+--------------+
| ip_来自 | ip_to |国家代码 |
+------------+------------+--------------+
| 1908932608 | 1909063679 |中国 |
+------------+------------+--------------+
一组中的 1 行(10.15 秒)

【问题讨论】:

    标签: mysql sql query-optimization mariadb


    【解决方案1】:
    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 
    

    速度很快,因为只比较了一个索引列。

    【讨论】:

      【解决方案2】:

      尝试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;
      

      【讨论】:

        猜你喜欢
        • 2018-12-20
        • 2020-05-06
        • 2015-10-11
        • 2017-02-28
        • 2020-08-20
        • 1970-01-01
        • 2010-10-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多