SQL中limit怎么用 分页查询的2种标准写法

请稍等。
昨天,我在调试电商后端的分页功能时,突然发现了一个有趣的细节。
当时,用户报告说 1 01 个页面加载速度非常慢。
我直接使用LIMIT 1 00, 1 0查看,发现随着数据量的增加,MySQL会扫描该偏移量处的全部1 00条数据,并将其丢弃。
我的 CPU 立即飙升到 9 0%。
如果更改写入方法并使用 WHERE last_id > 1 00 再次检查,速度应该会快 3 倍。

这让我想起了早期使用Oracle分页的日子。
我创建了一个 ROWNUM <= 5 0 的子查询的嵌套查询,甚至表统计时间都浪费在计算行数上。
然后我转而使用WITH 语句中的ROW_NUMBER() 来完成此操作。
但现在让我们看看使用 PostgreSQL 的窗口函数有多酷。
只需一行代码。

等一下,还有一件事。
最近在测试SQL Server 2 01 6 时发现一个奇怪的现象,用OFFSET 1 000 FETCH NEXT 1 0,明明有索引,但执行计划是扫描全表,检查完1 000条后直接截断。
查阅资料发现是索引参数max_rows设置得太低了。

话虽这么说,这个分​​页优化实际上是一个形而上的任务。
例如,如果您使用 Redis 缓存您的主页,如果用户请求接近某个 ID 的内容,则缓存可能会失败。
这时候只能多配置几个热点数据缓存策略了……

SQL笔试面试编程题-分页查询employees表,每5行一页,返回第2页的数据

说实话,当时我写SQL分页也很吃力。
我们获取employee表,根据emp_no查看第2 页的数据。
每页有 5 行。
直接编码最直观:
sql 从员工中选择 ORDER BY emp_no LIMIT 5 OFFSET 5 ;
但背后有一些点需要理清。
我们先来说说排序。
如果没有这一步,那就麻烦了。
例如,有些人按降序对 emp_no 进行排序,有些人则按随机顺序排序。
每次运行的结果都不一样,这是绝对不能接受的。
换句话说,
SQL 在 emp_no 订购
这是基础知识。
不要忘记添加 DESC 降序选项。
我们来谈谈分页。
记住以下公式:
页起始行 N = (页码
1 ) 每页行数
第 2 页应用 5 行,因此 OFFSET 也使用 5 行。
但有趣的是,这样做会减慢速度。
我曾经在一个拥有数千万员工的特定员工表上进行了测试。
使用OFFSET跳过5 00万行后,查询时间立即暴涨。
后来改为:
sql -
从上一页的最后一个 emp_no + 1 开始搜索 从员工中选择,其中 emp_no > 9 8 7 6 5 4 ORDER BY emp_no LIMIT 5 ;
这样效率要高得多。
还必须考虑边界条件。
例如,总行数正好是 9 ,但在第二页上只找到 4 行。
应用程序层必须能够处理空结果。
您还应该了解数据库之间的差异。
Oracle 使用 ROWNUM,而 SQL Server 使用 FETCH NEXT。
编写通用代码时还应该使用标准 SQL。

计算总行数的这一步是可选的:
sql SELECT CEIL(COUNT() / 5 .0) AS 员工总数;
不管怎样,对于分页来说,简单的场景用LIMIT/OFFSET就可以了,复杂的场景就得动动脑子了。
当时我接手了一个使用OFFSET跳过前2 00万的查询,花了3 分钟才得到结果。
无法直接修复它。
修改索引以匹配 WHERE 条件并在几秒钟内查看结果。
因此,这项工作应该根据实际数据量进行优化。