perf(metrics): a day of one metric reads from the index alone, built after boot (#5490)
#5490 "A day of one metric reads fast even cold". A cold 24 h series read measured 18.3 s against 63 ms warm (#5485): every sample's row sat on its own heap page. ix_plugin_metrics_series_value carries `value` (INCLUDE), so the read is an index-only scan; it replaces the plain series index from 0023. It is built once, with CREATE INDEX CONCURRENTLY from a task started after the app is serving, never in a migration, so the boot isn't held while it builds over the live table (#5220) and ingest and pages carry on. A build cut short by a restart leaves an INVALID index; the next boot drops and rebuilds it. Later boots find it present and only check. Postgres keeps it current on each insert, as it did the index it replaces. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,8 +25,12 @@ class PluginMetric(Base):
|
||||
__table_args__ = (
|
||||
Index("ix_plugin_metrics_module_resource_recorded",
|
||||
"source_module", "resource_name", "recorded_at"),
|
||||
Index("ix_plugin_metrics_module_resource_metric_recorded",
|
||||
"source_module", "resource_name", "metric_name", "recorded_at"),
|
||||
# One series over a time range, read from the index alone: `value` is
|
||||
# carried in it. Built after boot by core/metric_index.py, not by a
|
||||
# migration, since a build over the live table takes minutes (#5490).
|
||||
Index("ix_plugin_metrics_series_value",
|
||||
"source_module", "resource_name", "metric_name", "recorded_at",
|
||||
postgresql_include=["value"]),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user