优化 PostgreSQL 的 tablefunc
以实现大型数据集的多列透视
有效地将大型数据集从长格式转换为宽格式(旋转)对于数据分析至关重要。本文解决了使用 PostgreSQL 的 tablefunc
扩展进行多列透视的挑战和解决方案,特别是在处理数十亿行时。
解决旋转挑战
一个常见问题涉及使用 tablefunc
旋转具有多个变量的数据。 例如,将具有 time
、entity
、status
和 measurement
等列的数据转换为宽格式,其中每个 measurement
值占用一个单独的列。
找出效率低下的根本原因
效率低下的主要原因通常是由于 tablefunc
查询中的列排序不正确。 crosstab
函数需要特定的顺序:行标识符(定义数据分隔)必须是第一列,后面是任何其他列,最后是要旋转的值。 不正确的顺序(例如交换 time
和 entity
列)会导致行标识符的误解,从而显着影响性能。
解决方案:正确的列顺序
解决方案涉及仔细重新排序列以遵守crosstab
的要求。 下面的示例演示了此更正,其中 entity
是行标识符,timeof
是附加列:
<code class="language-sql">crosstab( 'SELECT entity, timeof, status, ct FROM t4 ORDER BY 1,2,3' ,$$VALUES (1::text), (0::text)$$)</code>
说明性示例和输出
此示例展示了修改后的查询,使用 dense_rank()
确保唯一的行标识符,使用 generate_series
定义透视列的数量:
<code class="language-sql">SELECT localt, entity , msrmnt01, msrmnt02, msrmnt03, msrmnt04, msrmnt05 -- , more? FROM crosstab( 'SELECT dense_rank() OVER (ORDER BY localt, entity)::int AS row_name , localt, entity , msrmnt, val FROM test ORDER BY localt, entity, msrmnt' , 'SELECT generate_series(1,5)' ) AS ct (row_name int, localt timestamp, entity int , msrmnt01 float8, msrmnt02 float8, msrmnt03 float8, msrmnt04 float8, msrmnt05 float8 );</code>
这种正确的方法可确保使用 tablefunc
进行高效的多列旋转,即使对于非常大的数据集也是如此。 正确的列排序对于获得最佳性能至关重要。
以上是如何使用 PostgreSQL 的 tablefunc 针对大型数据集高效实现多列透视?的详细内容。更多信息请关注PHP中文网其他相关文章!