ELECT
id,
INET_NTOA(numip) as ip, `source`, latitude, longitude, date_format(`time`, '%Y-%m-%d %h:%i:%s' ) as time
FROM
`geoip_online_landmark` limit 10,10
# currPage是前端传来的页数,通过limit m,n获取第1页内容,m是从0开始计算,且不包含第m条记录
SELECT
id
FROM
`biz_iplocation_db`.`geoip_online_landmark` where time > '2015-06-02' ORDER BY id DESC limit (currPage-1)*10,1
通过获取的id,通过id跳跃limit出10条记录
# 其中recordId就是上面sql语句查询的id
SELECT
id,
INET_NTOA(numip) as ip, `source`, latitude, longitude, date_format(`time`, '%Y-%m-%d %h:%i:%s' ) as time
FROM
`biz_iplocation_db`.`geoip_online_landmark` where id>=recordId limit 10
超高性能处理亿级数据—倒排序+分块查询
核心原理和上面的根据id进行查询分页相同
当数据达到1亿的数据量,当用户点击最后一页的时候就会非常的耗时,超过1800s,无法忍受
分块处理+倒排序查询
根据数据量分成2份,前半份用正排序查询,后半份用倒排序查询,理论上会提升2倍性能
最终结果会出现两边页数查询快中间页数查询慢
倒排序例子:
# 获取倒排序id
# 业务逻辑:计算出倒排序的偏移量
#int record = allCount-landmarkReqVO.getCurrPage()-1;
#landmarkReqVO.setRecord(record);
#landmarkReqVO.setAllCount(allCount);
SELECT
id
FROM
`biz_iplocation_db`.`geoip_online_landmark` where source='App',time>'2021-05-06' ORDER BY id DESC limit #{record},1
根据id倒排序查询出数据
SELECT
id,
INET_NTOA(numip) as ip, `source`, latitude, longitude, date_format(`time`, '%Y-%m-%d %h:%i:%s' ) as time
FROM
`biz_iplocation_db`.`geoip_online_landmark` where source='APP' and time>='2020-12-4' and AND id>= #{recordId} ORDER BY `id` DESC limit #{pageSize}
结果:当用户点击中间的页数时,是最慢的情况,测试1亿条记录的结果为:3分钟响应
问题不足
通过测试发现当添加多个条件查询时,耗时最长的sql语句为计算符合条件的总记录数
SELECT count(*) FROM `geoip_online_landmark` WHERE source = 'APP' AND time > '2015-06-09'