金三银四面试季,真实面试经历打开Mysql大门
面试官:我看到你在简历上进行了页面搜索。你能告诉我你是怎么做到的吗?
小贱:主要是利用limit来实现分页。
面试官:您能告诉我限制的具体原理吗?
小贱z:嗯...
我们日常开发中,经常需要返回表格的前几行或者中间几行数据,所以目前我们可以借助limit来实现这些需求。那么极限是如何使用的呢?
使用limit
limit的使用一般有两种方式:
1. SELECT * FROM TABLE LIMIT XXX;
2. SELECT * FROM TABLE LIMIT XXX, XXX;
如上所示,limit可以接受一个或两个参数,那么它们之间有什么区别呢?
limit 的使用语法如下:
SELECT … FROM … LIMIT OFFSET N;
第一个参数OFFSET:表示偏移量,表示返回的记录集中有多少条记录应该开始捕获数据。注意:初始偏移量为1而不是0;
第二个参数N:表示返回的最大记录行数。如果N = -1,则表示我们返回到最后一组记录的最后一行
示例:
//表示返回记录集的第3-5行
1. SELECT * FROM TABLE LIMIT 2, 3;
//表示返回记录集的第1-3行
2. SELECT * FROM TABLE LIMIT 3;
//等价于下面的写法
SELECT * FROM TABLE LIMIT 0, 3; // 同样表示返回记录集的第1-3行
极限的原理
极限的原理是什么?然后我们通过实验进行分析。实验说:众所周知,不标明mysql版本和存储引擎的mysql实验都是流氓,所以本次实验有mysql版本,存储引擎是innodb。
首先我们来做一个实验表。我们称之为 test_limit
。创建表的说明如下:
CREATE TABLE `test_limit` (
`id` INT NOT NULL AUTO_INCREMENT,
`a` INT NULL,
`b` INT NULL,
PRIMARY KEY (`id`)) ENGINE=InnoDB ;
表的结构非常简单,只是一个自增主键和两个整数。区域。如下:
然后我们插入10万条数据:
delimiter ;;
create procedure gen_data()
begin
declare i int;
set i=1;
while(i<=100000)do
insert into test_limit values(i, i, i);
set i=i+1;
end while;
end;;
delimiter ;
call gen_data();
结果为:
然后我们分析极限原理,取OFFSET值10、100、1000,返回最大数据N 均为5使用解释查看该sql的执行计划如下图所示:
1. explain select * from test_limit order by id limit 10, 5;
2. explain select * from test_limit order by id limit 100, 5;
3. explain select * from test_limit order by id limit 1000, 5;
执行计划中的行数是该sql检查的行数。如图,如果N=10,则总共扫描15个。线路,返回线路 11-15。如果N=100,则系统总共检查105行,以及101-105。返回行。如果 N=1000,则系统总共检查 1005 行并返回行 1001-1005。
从上面可以看出:limit指令首先检查OFFSET+N行,然后丢弃第一个OFFSET行并返回接下来的N行数据。
使用limit时可能出现的性能问题
从上面的分析可以看出,如果offset很大,扫描的行数也会增加,功耗会非常高。这是更频繁浏览时的情况。
对此,我们进行了一个简单的实验,实验结果如下:
从图中可以看出,如果OFFSET越大,查询时间就越长。
对子查询进行优化,得到如下结果:
从结果中可以看出,相比不使用辅助查询,查询时间减少了,而且效果不是那么明显。其原因在于数据量。那么减少的原因是什么呢?羊毛面料?同样,通过解释查询sql执行计划,结果如下:
从执行计划可以看出,子查询优化前的sql执行计划类型为ALL,即全表扫描;当使用子查询优化后,可以看到SQL执行计划类型为range和index。即使使用了索引,通过索引也能提高SQL查询性能。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。