应采用键集分页替代OFFSET-FETCH:以主键或唯一递增字段为游标,配合复合索引(如IX_logs_created),避免函数排序和NOT IN子查询,确保高效稳定。SQL Server 存储过程中怎么写分页批处理直接用 OFFSET-FETCH 做分页在大数据量下会越来越慢,尤其当 OFFSET 超过百万行时,SQL Server 仍要扫描前面所有行。更稳的做法是用「键集分页(Keyset Pagination)」:靠主键或唯一递增字段(如 id)做游标,每次只查下一批。实操建议:确保分页字段有索引——比如 CREATE INDEX IX_logs_created ON logs(created_at, id),复合索引顺序影响性能避免 ORDER BY NEWID() 或函数表达式排序,会导致无法走索引不要用 TOP @batchSize + NOT IN (SELECT ...),数据量大时子查询变全表扫描示例逻辑:DECLARE @lastId INT = 0;<br>WHILE @lastId IS NOT NULL<br>BEGIN<br> SELECT TOP 1000 id, content FROM logs <br> WHERE id > @lastId ORDER BY id;<br> IF @@ROWCOUNT = 0 BREAK;<br> SELECT @lastId = MAX(id) FROM (SELECT TOP 1000 id FROM logs WHERE id > @lastId ORDER BY id) t;<br>ENDMySQL 存储过程里怎么安全地批量更新百万行直接 UPDATE big_table SET status = 1 WHERE condition 容易锁表、占满 binlog、触发超时。必须拆成小事务 + 显式控制提交节奏。关键点:用 WHERE id BETWEEN ? AND ? 切片,别依赖 LIMIT 配合 ORDER BY,否则可能漏行或重复每次更新后加 DO SLEEP(0.1)(MySQL 5.7+),缓解主从延迟和 I/O 压力务必检查 innodb_buffer_pool_size 是否足够,否则频繁刷脏页反而拖慢错误现象:执行中报 Lock wait timeout exceeded,说明事务太久或锁冲突,这时应缩小批次(如从 5000 改为 1000)PostgreSQL 中用游标分批处理为什么比 LIMIT 更可靠因为 DECLARE c CURSOR FOR ... 是服务端游标,不把全部结果集拉到客户端内存,且支持 FETCH FORWARD 1000 精确取数,不受并发 DML 导致的 LIMIT OFFSET 错位影响。 AI智研社 AI智研社是一个专注于人工智能领域的综合性平台

更多推荐