Postgres如何动态获取表ID及该ID对同表总行数取模的结果
最优实现方案
目前性能最好、写法最简洁的是用窗口函数实现,仅需单次全表扫描即可完成计算,无需额外连接、CTE或分组操作:
SELECT id, id % COUNT(*) OVER () AS mod FROM tbl;
方案说明
COUNT(*) OVER ()是无分区的窗口函数,会自动计算全表总行数,并作为常量值附加到每一条返回记录上,无需额外的统计步骤- 整体查询时间复杂度为O(n),远优于自连接方案的O(n²),也比CTE方案少一次全表扫描,大表场景下性能优势非常明显
- 兼容所有支持SQL:2003标准窗口函数的数据库,包括MySQL 8.0+、PostgreSQL、Oracle、SQL Server等,且查询本身是原子操作,不会出现统计行数和计算取模时数据不一致的问题
低版本数据库兼容方案
如果使用的是不支持窗口函数的低版本数据库(如MySQL 5.x),可以用用户变量预存总行数实现,同样可以避免自连接的性能问题:
-- 先统计总行数存入变量 SET @total_row_count = (SELECT COUNT(*) FROM tbl); -- 计算取模结果 SELECT id, id % @total_row_count AS mod FROM tbl;
该方案时间复杂度为O(n),仅比窗口函数方案多一次轻量的总行数统计请求,性能也远优于自连接写法。
内容的提问来源于stack exchange,提问作者carlosV2
相关产品推荐
相关产品推荐

