含重复字段表的查询性能:为何扁平化表查询成本更低?
UNNEST操作的额外开销:查询
select sum(A) from tableA, unnest(facts) where dimA = 1001需要先过滤出dimA=1001的行,再对每行的facts数组执行unnest拆分操作。这个拆分过程会生成大量临时记录,需要额外的CPU资源处理数组解析、临时数据构造,而扁平化的tableB本身就存储了拆分后的结构,不需要这一步额外计算。统计信息偏差导致成本估算错误:数据库优化器依赖统计信息判断查询成本,如果
tableA中facts数组的统计数据(比如平均元素数量、数组长度分布)不准确,优化器会低估unnest后的实际数据量,误以为tableA的扫描成本更低,但实际执行时展开后的数据规模远超预期,导致实际成本飙升。索引支持力度不同:
tableB可能针对dimA字段创建了高效的单列索引或覆盖索引,能快速定位到符合条件的行并直接聚合;而tableA即使行数少,若没有针对dimA的合适索引,或者数据库对嵌套数组字段的索引支持有限,过滤dimA=1001时需要全表扫描,再加上unnest的开销,整体成本就会超过tableB。单条记录IO开销更高:
tableA的单条记录包含整个facts数组,单条数据体积远大于tableB的单条记录。读取tableA时,即使行数少,单条大记录的IO读取时间可能比读取tableB多条小记录的总时间更长;如果内存不足,unnest操作还会触发磁盘交换,进一步拉高IO成本。聚合阶段的额外开销:
tableA在unnest后需要对临时生成的大量记录做聚合计算,临时数据的内存存储、数据传输开销都比tableB直接对已有扁平化数据聚合要高,尤其是当facts数组包含大量元素时,这种差异会更明显。
内容的提问来源于stack exchange,提问作者denim

