-
Notifications
You must be signed in to change notification settings - Fork 900
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: Deletion from compressed chunks performance and behaviour #5802
Comments
Hi @mickael-choisnet What you ask is: Is there a way to skip vacuum, which is a good suggestion. Let me discuss this with the team and check what can be done. Thanks. |
Hi @sb230132, Thanks for the quick reply and asking about the possibility to skip the vacuum if needed (as it is triggered after the job anyway and without triggering it the chunk can no longer be queried efficiently). About what you explained, I wonder if it would be possible to keep whatever behavior is implemented when directly deleting from compressed chunk, as it is very fast and seems efficient regarding the SELECT results and plan. I'm not sure that I understand why there is 2 min spent during deleting and then 2 more during the next job run if the deleting already took care of decompressing + delete + recompressing? |
Any UPDATE/DELETE on compressed chunk will result in decompressing(~2min) + update/delete. Hope its clear now. |
Hi @sb230132, Thanks for the explanations. It looks like the chunk will be decompressed whether there are some rows to delete or not. I tried to delete various amount of rows and the duration was always the same. |
Decompression happens only if there are rows which match the WHERE clause. Please check below. If you mention a DELETE statement with segment by columns in WHERE clause, then only affected segments in compressed chunks are decompressed and deleted. Next delete will do nothing. Same is the case for UPDATE as well.
If you are still not convinced please provide a testcase for my better understanding. I will try to provide more details based on your testcase. |
Hi @sb230132, Indeed, a direct But my use case is with a DELETE using another table to target the rows. You can use what I suggested in my reproduce steps, for your test case it would be something like: DROP TABLE IF EXISTS public.device_to_delete;
CREATE TABLE public.device_to_delete(
id TEXT NOT NULL
);
INSERT INTO device_to_delete(id)
SELECT 3;
DROP INDEX IF EXISTS ix_device_to_delete_id;
CREATE INDEX ix_device_to_delete_id ON public.device_to_delete (id);
DELETE FROM metrics_compressed AS metrics
USING device_to_delete AS device
WHERE device.id = metrics.device_id;
-- you can add a condition on the date Here are the traces from my case: testing-db=# select table_name, case when status=1 then 'compressed' else 'uncompressed' end as compression_status from _timescaledb_catalog.chunk where hypertable_id = 138;
table_name | compression_status
----------------------+--------------------
_hyper_138_348_chunk | compressed
_hyper_138_349_chunk | compressed
_hyper_138_350_chunk | compressed
(3 rows)
Time: 0.481 ms
testing-db=# select * from replay_meter_deleted_staging;
id | fluid_id
---------+----------
1000001 | 1
(1 row)
Time: 0.352 ms
testing-db=# select count(*) from measures_simple m join replay_meter_deleted_staging r on r.id = m.meter_id and r.fluid_id = m.fluid_id;
count
-------
0
(1 row)
Time: 2.701 ms
releve-data-analytics-testing-db=# delete from measures_simple as measure using replay_meter_deleted_staging as meter where meter.id = measure.meter_id and meter.fluid_id = measure.fluid_id;
DELETE 0
Time: 790867.776 ms (13:10.868)
releve-data-analytics-testing-db=# select table_name, case when status=1 then 'compressed' else 'uncompressed' end as compression_status from _timescaledb_catalog.chunk where hypertable_id = 138;
table_name | compression_status
----------------------+--------------------
_hyper_138_348_chunk | uncompressed
_hyper_138_349_chunk | uncompressed
_hyper_138_350_chunk | uncompressed
(3 rows)
Time: 0.712 ms |
Hi @mickael-choisnet You are right, unfortunately as of today, the WHERE predicate with simple conditions having const literals has the optimisation implemented. We have a PR in the roadmap to increase scope of optimisation for any kind of WHERE predicates. With the implementation of the new PR we should be able to resolve this issue. |
Hi @sb230132 Thanks for the input. I'm eager to test this version, it could significantly improve the performance of my scenario, and we may eventually be able to implement the solution we want. |
Hi @mickael-choisnet |
Dear Author, This issue has been automatically marked as stale due to lack of activity. With only the issue description that is currently provided, we do not have enough information to take action. If you have or find the answers we would need, please reach out. Otherwise, this issue will be closed in 30 days. Thank you! |
@sb230132 @jnidzwetzki Is this ticket a duplicate of some other ticket? Is the "where" predicate improvement still on your roadmap? Whatever it is, and whatever you decision, IMHO, this ticket does not deserve automatic culling. |
Hello @wrobell, Thanks for getting back to us. I can confirm that the issue is still in the backlog. However, it seems that the issue was mislabeled and as a result, the stale bot processed it last night. I have corrected the labels and the issue will remain open until it is resolved. I apologize for any inconvenience this may have caused. |
thank you |
Our team met this issue as well. For our case is very suitable to drop segments from compressed chunks directly, using So from our side some proposal has been born: Can timescale query planner use this internally somehow? From a distance the possible algorithm seems to be simple: If PS. @sb230132 mentioned that
If you have a bit of time are you able, probably, to disclose possible risks of such deletion bit more? Our team will be very pleased. Currently I see only one possible problem: if chunk has recently added new data and was not recompressed some tuples can be not compressed, marked as Lines 312 to 316 in e1676ce
By the way, is it possible to obtain such chunk state via SQL? |
Hi there. Seems this issue was addressed in version 2.17. PR in question: #6882 Have you had the time to check it out? |
Hi, Unfortunately, I haven't had time lately to check the latest improvements made by the team. Thanks for the news tho, I'll try to test this version as soon as possible as it could well be a must-have if it's an effective way to delete data in compressed chunks. |
Feel free to chime in here with your findings. Thanks! |
What type of bug is this?
Performance issue
What subsystems and features are affected?
Compression
What happened?
I did some tests regarding the new feature which allows deleting rows from compressed chunks.
I have a few concerns that I would like to share regarding performance.
The use case is this:
We need to be able to purge data, every day, up to about 3000 devices for over a year of data.
We have a hypertable with 14 day chunks containing indexes (1/day/device for this case, but in our real world data we also have 1/hour/device).
I generated random data for 3 million meters for 1 month to have a sample to do my tests and then project the results.
Here is what I observed:
Delete from compressed chunk
3000 is the number of IDs targeted for delete, but there is 42 000 row really affected
(The chunk size is not really affected for 3000 devices, but for 6000 it shows a slight decrease when deleting from hypertable)
Delete from hypertable
It seems the intended way to delete rows from compressed chunks is through the hypertable directly, however it does take quite some time.
For 1 chunk of 14 days: 2 min delete + 3 min autovacuum + 2 min compression job = 7 min.
If I project this result for 18 months, which is likely our present use case but will grow with time, it goes up to ~270 min (~4h).
It sure is faster than decompressing/deleting/compressing the chunks, but it is still not really efficient for our use case (we got 3 hypertables this size to handle and 2 smaller).
Would it be possible to skip the autovacuum part?
What about the 2 min of the delete operation if the compression policy job needs the same time to effectively delete the data afterwards? Is there a mean to gain time here?
Furthermore, it seems targeting directly the compressed chunk can achieve the same result in a faster way.
It just lacks the final deletion from the chunk through the job (or so it seems).
Which would leave us with just ~10 sec operation + 2 min compression job.
Was it intended to be able to delete data by targeting directly the compressed chunks?
Could you explore this removal method to speed up the overall process?
For the record, I've created a table with 18 months of random data and tried to delete rows for 1500 devices and gave up after 1h30 of processing the delete statement.
I hesitated between a bug (the deletion from the compressed chunk seems to be an option but not fully implemented) and an enhancement because, in the end, the functionality is operational. Please feel free to adjust as you see fit.
TimescaleDB version affected
2.11.0
PostgreSQL version used
PostgreSQL 14.5 (Debian 14.5-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
What operating system did you use?
Debian GNU/Linux 10 (buster) (10.13)
What installation method did you use?
Deb/Apt
What platform did you run on?
Microsoft Azure Cloud
Relevant log output and stack trace
Here is the SELECT query EXPLAIN before any delete: https://explain.depesz.com/s/rTeH
Here is the same plan after deleting directly from compressed chunk: https://explain.depesz.com/s/AHtc
Here is the same plan if we do not run the compression job after deleting from the hypertable: https://explain.depesz.com/s/951
How can we reproduce the bug?
Here are the scripts used to produce the results.
The text was updated successfully, but these errors were encountered: