分区表不直接加速 GROUP BY,它靠让数据库少扫数据来间接提速——关键看 WHERE 条件能否触发分区剪枝;若查询未带分区键的确定性等值或范围条件(如 WHERE dt >= '2026-07-01'),则仍需扫描全部分区,GROUP BY 无法受益。

分区表不直接加速 GROUP BY,它靠让数据库少扫数据来间接提速——关键看 WHERE 条件能不能触发分区剪枝。
为什么加了分区,GROUP BY 还是慢?
常见错误是只建了分区,但查询没带分区键过滤条件。比如按 dt(日期)分区的表,执行 SELECT region, SUM(sales) FROM orders GROUP BY region,引擎仍得扫描所有分区,分区白建。
- 分区剪枝必须依赖
WHERE中对分区键的**确定性范围或等值条件**,例如WHERE dt >= '2026-07-01' AND dt -
GROUP BY字段本身是不是分区键不重要,但若两者组合使用(如WHERE dt BETWEEN ... GROUP BY region),且region上有索引,效果最好 - MySQL 8.0+、PostgreSQL 12+、SQL Server 2016+ 才原生支持高效剪枝;旧版本即使语法支持,执行计划里也常显示
type: ALL或Partition: all
怎么验证分区剪枝是否生效?
别信“建了就有效”,必须看执行计划。不同数据库命令不同,但核心都是找 Extra 或 Partition 字段:
- MySQL:用
EXPLAIN FORMAT=TREE或EXPLAIN PARTITIONS,确认partitions列只列出目标分区(如p202607,p202608),不是all - PostgreSQL:用
EXPLAIN (ANALYZE, VERBOSE),看输出里是否有Partition Elimination提示,以及实际扫描的子表名(如orders_202607) - SQL Server:用
SET STATISTICS XML ON,在执行计划 XML 中搜索PartitionCount和ActualPartitionCount,二者应相等且远小于总分区数
分区数量和大小怎么设才不影响 GROUP BY?
分区太多会抬高调度开销,太少又起不到剪枝效果。实测下来,单个分区行数在 500 万–2000 万之间较稳,对应物理大小约 100–250MB。
- 查 MySQL 分区大小:
SELECT PARTITION_NAME, TABLE_ROWS, DATA_LENGTH FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'orders' - 查 PostgreSQL 分区大小:
SELECT pg_total_relation_size('orders_202607'),再结合\d+ orders看结构 - SQL Server 的
sys.dm_db_partition_stats.row_count是近似值,需配合DBCC UPDATEUSAGE校准后再判断 - 避免按
user_id % 100这类哈希字段分区后,再查WHERE status = 'paid'——无法剪枝,全扫照旧
真正容易被忽略的是:分区剪枝不是自动发生的,它完全依赖优化器能否从 WHERE 条件中推导出分区边界。哪怕条件写成 WHERE DATE(dt) = '2026-07-15',也会因函数调用导致剪枝失效——必须用原生列做范围比较。


















