MySQL面试题:亿级数据量连表查询,取结果第10000到11000条

1. 题目

表A通过外键tid关联表B,表A有10亿条数据,表B有4亿条数据,连表查询A和B,取查询结果的第10000到11000条数据

2. 解决方案

(非标准答案,参考网上资料结合自己的思考,参考资料:使用子查询优化分页查询

  1. 先查找表A的第10000到11000条数据:不要limit直接分页查,第10000条记录前的记录会产生I/O开销——先查第10000条记录的主键(SELECT id FROM A LIMIT 9999, 1),分页时通过where语句跳过前10000条记录(SELECT * FROM A WHERE id >=  第10000条记录的主键 LIMIT 1000)
  2. 连表查询(没想到SQL层面的优化,但如果机器允许,可考虑加大join buffer
-- 查询表A第10000条记录的主键值
create temporary table `offset` as
select id from A order by id limit 9999, 1;
-- 连表
select a.id as aid, B.id as bid, a.tid as tid
from (
    select * from A where id >= (
        select id from `offset` limit 1)
    order by id limit 1000
) as a
inner join B on a.tid = B.id;

3. 模拟测试

3.1 建表

受限于硬件,表A大小1000万,表B大小400万

表A,外键tid乱序
表B

3.2 查询时间

(1)直接连表分页查询

SELECT A.id, A.tid, B.id FROM A
INNER JOIN B ON A.tid = B.id
ORDER BY A.id LIMIT 9999, 1000;

(2)优化后


差别不明显,下面尝试取从第20万条开始的1000条数据

PS:上面结果可能因为缓存并不准确,因此下面先查优化后的结果,在查优化前的结果(这里我第一次先查优化前的结果,时间是达到了17秒的)

(1)优化后

(2)直接连表分页查询

SELECT A.id, A.tid, B.id FROM A
INNER JOIN B ON A.tid = B.id
ORDER BY A.id LIMIT 199999, 1000; -- 从第20万条开始的1000条


差别还是蛮大的……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值