<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://iandoob.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=2A02%3A8012%3A10C9%3A0%3A1454%3A8E3B%3AF3BA%3A4D18</id>
	<title>Ian Doob Technology - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://iandoob.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=2A02%3A8012%3A10C9%3A0%3A1454%3A8E3B%3AF3BA%3A4D18"/>
	<link rel="alternate" type="text/html" href="https://iandoob.net/index.php/Special:Contributions/2A02:8012:10C9:0:1454:8E3B:F3BA:4D18"/>
	<updated>2026-05-14T02:02:28Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.7</generator>
	<entry>
		<id>https://iandoob.net/index.php?title=TimeScale_Training&amp;diff=65</id>
		<title>TimeScale Training</title>
		<link rel="alternate" type="text/html" href="https://iandoob.net/index.php?title=TimeScale_Training&amp;diff=65"/>
		<updated>2025-04-14T09:53:27Z</updated>

		<summary type="html">&lt;p&gt;2A02:8012:10C9:0:1454:8E3B:F3BA:4D18: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Setup ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SET search_path = &amp;quot;$user&amp;quot;, public, &amp;quot;timescaledb_information&amp;quot;;&lt;br /&gt;
SET timezone TO &#039;Europe/Berlin&#039;;&lt;br /&gt;
&lt;br /&gt;
\dv timescaledb_information.*&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DROP TABLE IF EXISTS metrics;&lt;br /&gt;
CREATE TABLE metrics (id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY, &lt;br /&gt;
                      device_time timestamptz NOT NULL, &lt;br /&gt;
                      device_id integer, &lt;br /&gt;
                      cpu_usage numeric);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create Hypertable ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT create_hypertable(&#039;metrics&#039;, by_range(&#039;device_time&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ERROR:  cannot create a unique index without the column &amp;quot;device_time&amp;quot; (used in partitioning) &amp;lt;/br&amp;gt;&lt;br /&gt;
HINT:  If you&#039;re creating a hypertable on a table with a primary key, ensure the partitioning column is part of the primary or composite key.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE metrics DROP CONSTRAINT metrics_pkey;&lt;br /&gt;
ALTER TABLE metrics ADD PRIMARY KEY (id, device_time);&lt;br /&gt;
SELECT create_hypertable(&#039;metrics&#039;, by_range(&#039;device_time&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the existing table already has data in it then you must use the &amp;quot;migrate_data&amp;quot; option. &amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT create_hypertable(&#039;metrics&#039;, by_range(&#039;device_time&#039;), migrate_data =&amp;gt; true);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Chunk Interval ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT create_hypertable(&#039;metrics&#039;, by_range(&#039;time&#039;, INTERVAL &#039;1 month&#039;));&lt;br /&gt;
SELECT set_chunk_time_interval(&#039;metrics&#039;, INTERVAL &#039;14 days&#039;);&lt;br /&gt;
&lt;br /&gt;
SELECT hypertable_name, column_name, time_interval FROM timescaledb_information.dimensions;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Generate Time Series Data ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TRUNCATE TABLE metrics RESTART IDENTITY;&lt;br /&gt;
INSERT INTO metrics (device_time, device_id, cpu_usage) (&lt;br /&gt;
SELECT time, device_id, random()*100 as cpu_usage &lt;br /&gt;
  FROM generate_series(date_trunc(&#039;hour&#039;,now()) - INTERVAL &#039;6 months&#039;, now(), INTERVAL &#039;5 minutes&#039;) as time, &lt;br /&gt;
       generate_series(1,1000) device_id&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Table Size ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT PG_SIZE_PRETTY (pg_total_relation_size(&#039;metrics&#039;));&lt;br /&gt;
SELECT PG_SIZE_PRETTY (hypertable_size(&#039;metrics&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Check Statistics ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ANALYZE metrics;&lt;br /&gt;
SELECT tablename, attname, n_distinct FROM pg_stats WHERE tablename = &#039;metrics&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examine Chunks ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\d+ metrics&lt;br /&gt;
SELECT MAX(device_time), MIN(device_time) FROM _timescaledb_internal.&amp;lt;chunk&amp;gt;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Compression (Old) ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE metrics &lt;br /&gt;
SET (timescaledb.compress, &lt;br /&gt;
     timescaledb.compress_segmentby=&#039;device_id&#039;, &lt;br /&gt;
     timescaledb.compress_orderby=&#039;device_time DESC&#039;);&lt;br /&gt;
	 &lt;br /&gt;
SELECT compress_chunk(c) from show_chunks(&#039;metrics&#039;) c;&lt;br /&gt;
&lt;br /&gt;
SELECT pg_size_pretty(before_compression_total_bytes) as before,&lt;br /&gt;
       pg_size_pretty(after_compression_total_bytes) as after&lt;br /&gt;
  FROM hypertable_compression_stats(&#039;metrics&#039;);&lt;br /&gt;
  &lt;br /&gt;
SELECT add_compression_policy(&#039;metrics&#039;, INTERVAL &#039;1 days&#039;);&lt;br /&gt;
&lt;br /&gt;
SELECT remove_compression_policy(&#039;metrics&#039;);&lt;br /&gt;
SELECT decompress_chunk(c, true) FROM show_chunks(&#039;metrics&#039;) c;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Compression (New) ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE metrics SET (&lt;br /&gt;
   timescaledb.enable_columnstore = true, &lt;br /&gt;
   timescaledb.segmentby = &#039;device_id&#039;);&lt;br /&gt;
   &lt;br /&gt;
CALL add_columnstore_policy(&#039;metrics&#039;, after =&amp;gt; INTERVAL &#039;1d&#039;);&lt;br /&gt;
&lt;br /&gt;
SELECT pg_size_pretty(before_compression_total_bytes) as before,&lt;br /&gt;
       pg_size_pretty(after_compression_total_bytes) as after&lt;br /&gt;
  FROM hypertable_compression_stats(&#039;metrics&#039;);&lt;br /&gt;
  &lt;br /&gt;
SELECT pg_size_pretty(before_compression_table_bytes) as before_table,&lt;br /&gt;
       pg_size_pretty(before_compression_index_bytes) as before_index,&lt;br /&gt;
       pg_size_pretty(before_compression_toast_bytes) as before_toast,&lt;br /&gt;
       pg_size_pretty(before_compression_total_bytes) as before_total,&lt;br /&gt;
       pg_size_pretty(after_compression_table_bytes) as after_table,&lt;br /&gt;
       pg_size_pretty(after_compression_index_bytes) as after_index,&lt;br /&gt;
       pg_size_pretty(after_compression_toast_bytes) as after_toast,&lt;br /&gt;
       pg_size_pretty(after_compression_total_bytes) as after_total&lt;br /&gt;
  FROM hypertable_columnstore_stats(&#039;metrics&#039;);&lt;br /&gt;
  &lt;br /&gt;
SELECT * FROM timescaledb_information.jobs WHERE proc_name=&#039;policy_compression&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tablespaces ==&lt;br /&gt;
https://docs.timescale.com/self-hosted/latest/manage-storage &amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLESPACE historic_data OWNER postgres LOCATION &#039;/home/postgres/timescale&#039;;&lt;br /&gt;
&lt;br /&gt;
SELECT show_chunks(&#039;metrics&#039;, older_than =&amp;gt; INTERVAL &#039;5 months&#039;);&lt;br /&gt;
&lt;br /&gt;
SELECT move_chunk(&lt;br /&gt;
  chunk =&amp;gt; &#039;_timescaledb_internal._hyper_1_4_chunk&#039;,&lt;br /&gt;
  destination_tablespace =&amp;gt; &#039;historic_data&#039;,&lt;br /&gt;
  index_destination_tablespace =&amp;gt; &#039;historic_data&#039;,&lt;br /&gt;
  reorder_index =&amp;gt; &#039;_timescaledb_internal._hyper_1_4_chunk_netdata_time_idx&#039;,&lt;br /&gt;
  verbose =&amp;gt; TRUE&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
https://docs.timescale.com/timescaledb/latest/overview/limitations &amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Time dimensions (columns) used for partitioning cannot have NULL values.&lt;br /&gt;
* Unique indexes must include all columns that are partitioning dimensions. &lt;br /&gt;
* UPDATE statements that move values between partitions (chunks) are not supported.&lt;br /&gt;
* Foreign key constraints from a hypertable referencing another hypertable are not supported.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT name, setting, short_desc FROM pg_settings WHERE name like &#039;timescaledb.%&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>2A02:8012:10C9:0:1454:8E3B:F3BA:4D18</name></author>
	</entry>
	<entry>
		<id>https://iandoob.net/index.php?title=TimeScale_Training&amp;diff=64</id>
		<title>TimeScale Training</title>
		<link rel="alternate" type="text/html" href="https://iandoob.net/index.php?title=TimeScale_Training&amp;diff=64"/>
		<updated>2025-04-14T09:52:48Z</updated>

		<summary type="html">&lt;p&gt;2A02:8012:10C9:0:1454:8E3B:F3BA:4D18: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Setup ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SET search_path = &amp;quot;$user&amp;quot;, public, &amp;quot;timescaledb_information&amp;quot;;&lt;br /&gt;
SET timezone TO &#039;Europe/Berlin&#039;;&lt;br /&gt;
&lt;br /&gt;
\dv timescaledb_information.*&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DROP TABLE IF EXISTS metrics;&lt;br /&gt;
CREATE TABLE metrics (id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY, &lt;br /&gt;
                      device_time timestamptz NOT NULL, &lt;br /&gt;
                      device_id integer, &lt;br /&gt;
                      cpu_usage numeric);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create Hypertable ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT create_hypertable(&#039;metrics&#039;, by_range(&#039;device_time&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ERROR:  cannot create a unique index without the column &amp;quot;device_time&amp;quot; (used in partitioning) &amp;lt;/br&amp;gt;&lt;br /&gt;
HINT:  If you&#039;re creating a hypertable on a table with a primary key, ensure the partitioning column is part of the primary or composite key.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE metrics DROP CONSTRAINT metrics_pkey;&lt;br /&gt;
ALTER TABLE metrics ADD PRIMARY KEY (id, device_time);&lt;br /&gt;
SELECT create_hypertable(&#039;metrics&#039;, by_range(&#039;device_time&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the existing table already has data in it then you must use the &amp;quot;migrate_data&amp;quot; option. &amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT create_hypertable(&#039;metrics&#039;, by_range(&#039;device_time&#039;), migrate_data =&amp;gt; true);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Chunk Interval ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT create_hypertable(&#039;metrics&#039;, by_range(&#039;time&#039;, INTERVAL &#039;1 month&#039;));&lt;br /&gt;
SELECT set_chunk_time_interval(&#039;metrics&#039;, INTERVAL &#039;14 days&#039;);&lt;br /&gt;
&lt;br /&gt;
SELECT hypertable_name, column_name, time_interval FROM timescaledb_information.dimensions;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Generate Time Series Data ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TRUNCATE TABLE metrics RESTART IDENTITY;&lt;br /&gt;
INSERT INTO metrics (device_time, device_id, cpu_usage) (&lt;br /&gt;
SELECT time, device_id, random()*100 as cpu_usage &lt;br /&gt;
  FROM generate_series(date_trunc(&#039;hour&#039;,now()) - INTERVAL &#039;6 months&#039;, now(), INTERVAL &#039;5 minutes&#039;) as time, &lt;br /&gt;
       generate_series(1,1000) device_id&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Table Size ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT PG_SIZE_PRETTY (pg_total_relation_size(&#039;metrics&#039;));&lt;br /&gt;
SELECT PG_SIZE_PRETTY (hypertable_size(&#039;metrics&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Check Statistics ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ANALYZE metrics;&lt;br /&gt;
SELECT tablename, attname, n_distinct FROM pg_stats WHERE tablename = &#039;metrics&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examine Chunks ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\d+ metrics&lt;br /&gt;
SELECT MAX(device_time), MIN(device_time) FROM _timescaledb_internal.&amp;lt;chunk&amp;gt;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Compression (Old) ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE metrics &lt;br /&gt;
SET (timescaledb.compress, &lt;br /&gt;
     timescaledb.compress_segmentby=&#039;device_id&#039;, &lt;br /&gt;
     timescaledb.compress_orderby=&#039;device_time DESC&#039;);&lt;br /&gt;
	 &lt;br /&gt;
SELECT compress_chunk(c) from show_chunks(&#039;metrics&#039;) c;&lt;br /&gt;
&lt;br /&gt;
SELECT pg_size_pretty(before_compression_total_bytes) as before,&lt;br /&gt;
       pg_size_pretty(after_compression_total_bytes) as after&lt;br /&gt;
  FROM hypertable_compression_stats(&#039;metrics&#039;);&lt;br /&gt;
  &lt;br /&gt;
SELECT add_compression_policy(&#039;metrics&#039;, INTERVAL &#039;1 days&#039;);&lt;br /&gt;
&lt;br /&gt;
SELECT remove_compression_policy(&#039;metrics&#039;);&lt;br /&gt;
SELECT decompress_chunk(c, true) FROM show_chunks(&#039;metrics&#039;) c;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Compression (New) ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER TABLE metrics SET (&lt;br /&gt;
   timescaledb.enable_columnstore = true, &lt;br /&gt;
   timescaledb.segmentby = &#039;device_id&#039;);&lt;br /&gt;
   &lt;br /&gt;
CALL add_columnstore_policy(&#039;metrics&#039;, after =&amp;gt; INTERVAL &#039;1d&#039;);&lt;br /&gt;
&lt;br /&gt;
SELECT pg_size_pretty(before_compression_total_bytes) as before,&lt;br /&gt;
       pg_size_pretty(after_compression_total_bytes) as after&lt;br /&gt;
  FROM hypertable_compression_stats(&#039;metrics&#039;);&lt;br /&gt;
  &lt;br /&gt;
SELECT pg_size_pretty(before_compression_table_bytes) as before_table,&lt;br /&gt;
       pg_size_pretty(before_compression_index_bytes) as before_index,&lt;br /&gt;
	   pg_size_pretty(before_compression_toast_bytes) as before_toast,&lt;br /&gt;
	   pg_size_pretty(before_compression_total_bytes) as before_total,&lt;br /&gt;
	   pg_size_pretty(after_compression_table_bytes) as after_table,&lt;br /&gt;
       pg_size_pretty(after_compression_index_bytes) as after_index,&lt;br /&gt;
	   pg_size_pretty(after_compression_toast_bytes) as after_toast,&lt;br /&gt;
	   pg_size_pretty(after_compression_total_bytes) as after_total&lt;br /&gt;
  FROM hypertable_columnstore_stats(&#039;metrics&#039;);&lt;br /&gt;
  &lt;br /&gt;
SELECT * FROM timescaledb_information.jobs WHERE proc_name=&#039;policy_compression&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tablespaces ==&lt;br /&gt;
https://docs.timescale.com/self-hosted/latest/manage-storage &amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLESPACE historic_data OWNER postgres LOCATION &#039;/home/postgres/timescale&#039;;&lt;br /&gt;
&lt;br /&gt;
SELECT show_chunks(&#039;metrics&#039;, older_than =&amp;gt; INTERVAL &#039;5 months&#039;);&lt;br /&gt;
&lt;br /&gt;
SELECT move_chunk(&lt;br /&gt;
  chunk =&amp;gt; &#039;_timescaledb_internal._hyper_1_4_chunk&#039;,&lt;br /&gt;
  destination_tablespace =&amp;gt; &#039;historic_data&#039;,&lt;br /&gt;
  index_destination_tablespace =&amp;gt; &#039;historic_data&#039;,&lt;br /&gt;
  reorder_index =&amp;gt; &#039;_timescaledb_internal._hyper_1_4_chunk_netdata_time_idx&#039;,&lt;br /&gt;
  verbose =&amp;gt; TRUE&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
https://docs.timescale.com/timescaledb/latest/overview/limitations &amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Time dimensions (columns) used for partitioning cannot have NULL values.&lt;br /&gt;
* Unique indexes must include all columns that are partitioning dimensions. &lt;br /&gt;
* UPDATE statements that move values between partitions (chunks) are not supported.&lt;br /&gt;
* Foreign key constraints from a hypertable referencing another hypertable are not supported.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT name, setting, short_desc FROM pg_settings WHERE name like &#039;timescaledb.%&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>2A02:8012:10C9:0:1454:8E3B:F3BA:4D18</name></author>
	</entry>
</feed>