游客发表

数据库分页查询sql语句

发帖时间:2026-10-17 04:58:20

数据库分页这事儿,数据说穿了就是库分“别一次全拿出来”。我见过太多新手写查询,页查语句直接`SELECT * FROM table`,数据然后前端卡死,库分服务端内存爆掉。页查语句真正干活的数据分页SQL,核心就一句话:**先定位,库分再取数**。页查语句

最经典的数据是MySQL的`LIMIT`写法。比如你要看第100页,库分每页20条,页查语句那就是数据`LIMIT 1980, 20`。这玩意儿简单,库分但有个坑——偏移量越大,页查语句查询越慢。为啥?因为数据库得先数出前1980条扔掉,再取你要的20条。就像翻一本厚书,你从第1页翻到第1980页,手都酸了。我做过测试,偏移量到十万级,响应时间翻倍不止。

那怎么办?换个思路:**记住上一次的位置**。比如按自增ID排序,你上次看到ID=1980,那下一页直接`WHERE id > 1980 ORDER BY id LIMIT 20`。这样数据库走索引,嗖一下就定位到了。代价是你得在业务层记住这个游标,不能随便跳页。但话说回来,用户真的会一口气翻到第500页吗?大多数场景下,他翻到第三页就烦了。

PostgreSQL的写法稍微优雅点,用`OFFSET ... FETCH NEXT`,语法更标准,但原理跟MySQL一个德行。倒是SQL Server有个`ROW_NUMBER() OVER()`窗口函数,能精确控制行号范围,适合那种需要复杂过滤后再分页的场景。比如你要先按某个字段去重,再排序分页,这时候`ROW_NUMBER()`比直接加`ORDER BY`靠谱得多。

有个细节容易被忽略:**排序字段必须有唯一性**。你按`create_time`排序,结果同一秒有两条记录,分页就乱了——同一行数据可能出现在两页里。我踩过这坑,后来强制加个`id`作为次级排序键,问题立刻消失。别嫌麻烦,这是硬道理。

还有个实用技巧,分页时顺便查个总数。`SELECT COUNT(*)`全表扫一遍,数据量大时很伤。我习惯用`SQL_CALC_FOUND_ROWS`(MySQL专属),或者干脆把总数缓存起来,比如用Redis存个key,每小时更新一次。用户看到的总数差个几十条,他根本察觉不到,但你的数据库能喘口气。

最后说个反直觉的事:有时候不分页反而更快。如果查询结果本身就只有几十条,你还硬套个`LIMIT 10 OFFSET 0`,那是画蛇添足。数据库优化器虽然聪明,但多一层包装就多一分开销。我见过有人对字典表分页,纯属没事找事。

分页SQL没有银弹,核心就三件事:明确数据量级、选对定位方式、保证排序稳定。你把这三点想透了,剩下的都是语法糖。

    热门排行

    友情链接