您现在已经了解了如何为您的 NYC 出租车行程数据创建超表并进行查询。当摄取像这样的数据集时,几乎不需要更新旧数据,并且随着时间的推移,表中的数据量会增长。随着时间的推移,您最终会得到大量数据,由于这些数据大多是不可变的,您可以对其进行压缩以节省空间并避免产生额外的成本。

可以使用面向磁盘的压缩,例如 ZFS 和 Btrfs 提供的支持,但由于 TimescaleDB 是为处理面向事件的数据(例如时序数据)而构建的,因此它本身就支持压缩超表中的数据。

TimescaleDB 压缩允许您以效率更高的格式存储数据,与普通的 PostgreSQL 表相比,压缩率高达 20 倍,但这当然高度依赖于数据和配置。

TimescaleDB 压缩在 PostgreSQL 中以原生方式实现,不需要特殊的存储格式。相反,它依赖于 PostgreSQL 的功能,在压缩之前将数据转换为列式格式。列式格式的使用可以实现更好的压缩率,因为相似的数据相邻存储。有关压缩格式外观的更多详细信息,您可以查看压缩设计部分。

压缩数据的一个有益的副作用是,某些查询速度显着加快,因为需要读取到内存中的数据更少。

  1. 连接到包含数据集的 Timescale 数据库,例如使用 psql

  2. 使用 ALTER TABLE 命令在表上启用压缩,并选择合适的 segment-by 和 order-by 列

    ALTER TABLE rides
    SET (
    timescaledb.compress,
    timescaledb.compress_segmentby='vendor_id',
    timescaledb.compress_orderby='pickup_datetime DESC'
    );

    根据 segment-by 和 order-by 列的选择,您可能会获得非常不同的性能和压缩率。要了解有关如何选择正确列的更多信息,请参阅此处

  3. 您可以手动压缩超表的所有数据块,方法是使用如下所示的 compress_chunk

    SELECT compress_chunk(c) from show_chunks('rides') c;

    您还可以通过添加压缩策略自动化压缩,这将在下面介绍。

  4. 现在您已经压缩了表,您可以比较压缩前后数据集的大小

    SELECT
    pg_size_pretty(before_compression_total_bytes) as before,
    pg_size_pretty(after_compression_total_bytes) as after
    FROM hypertable_compression_stats('rides');

    这显示了数据使用方面的显着改进

    before | after
    ---------+--------
    1741 MB | 603 MB

为了避免每次有一些数据要压缩时都运行压缩步骤,您可以设置压缩策略。压缩策略允许您压缩比特定年龄更旧的数据,例如,压缩所有超过 8 天的数据块

SELECT add_compression_policy('rides', INTERVAL '8 days');

压缩策略按计划定期运行,默认情况下每天一次,这意味着使用上述设置,您最多可能有 9 天的未压缩数据。

您可以在add_compression_policy部分找到有关压缩策略的更多信息。

之前,压缩设置为按 vendor_id 列值进行分段。这意味着通过在该列上进行过滤或分组来获取数据将更有效率。排序也设置为时间降序,因此如果您运行尝试按该顺序对数据进行排序的查询,您应该会看到性能优势。

例如,如果您运行上一节中的查询示例

SELECT rate_code, COUNT(vendor_id) AS num_trips
FROM rides
WHERE pickup_datetime < '2016-01-08'
GROUP BY rate_code
ORDER BY rate_code;

当数据集被压缩时和解压缩时,您应该会看到明显的性能差异。通过运行之前的查询,解压缩数据集并再次运行它,同时计时执行时间,亲自尝试一下。您可以通过运行以下命令在 psql 中启用计时查询时间

\timing

要解压缩整个数据集,请运行

SELECT decompress_chunk(c) from show_chunks('rides') c;

在一个示例设置中,观察到的加速性能非常显着,压缩时为 700 毫秒,解压缩时为 1.2 秒。

亲自尝试一下,看看您得到什么!

关键词

在此页面上发现问题?报告问题 或 在 GitHub 上编辑此页