> I'm spinning up a new Postgresql 14 database where I'll have to store a
couple years worth of time series data at the rate of single-digit millions
of rows per day.
I think you absolutely need to use partitioning for the following reasons:
1. maintenance and roll-off of older data
2. indexes are much smaller
3. performance is predictable (if partition pruning kicks in)

Postgres 14 improved partitioning quite a bit. I used it in Postgres 9 and
there was a lot of locking on partition hierarchy when you add/drop
partition tables.
Having thousands of partitions shouldn't be a problem, BUT you will incur
cost on query planning, which is usually under 0.1 second on modern
hardware.


On Tue, Aug 2, 2022 at 5:55 AM Rick Otten <rottenwindf...@gmail.com> wrote:

>
>
> On Mon, Aug 1, 2022 at 10:16 AM Rick Otten <rottenwindf...@gmail.com>
> wrote:
>
>>
>>> The other problem I ran into, which I'm still building a test case for
>>> and I fear might be a bug if I can easily reproduce it,
>>> is if I did the original select in a CTE, and then did a sort outside of
>>> the CTE, even though the CTE found 0 rows, the database
>>> still spent a _ton_ of time sorting those 0 rows:
>>> ```
>>>    ->  Sort  (cost=70.03..72.53 rows=1000 width=112) (actual
>>> time=84848.452..84848.453 rows=0 loops=1)
>>> ```
>>> Once I can reproduce this on test data I'll be able to pin down more
>>> closely what is happening and tell if I'm just reading
>>> the explain plan wrong or if something is broken.  It was getting mixed
>>> up with the lack of pruning/index usage problem.
>>>
>>> I'll report back again next week.  Anyway it is looking to me like it
>>> doesn't really matter (within reason) from a performance
>>> perspective how many partitions we use for our data set and query
>>> patterns.  We should be able to pick the most convenient
>>> from an archiving and data management perspective instead.
>>>
>>>
>> This behavior is definitely consistent.  0 rows end up slower than when I
>> find some rows in my CTE:
>> ```
>>    ->  Sort  (cost=109.44..113.19 rows=1500 width=112) (actual
>> time=87110.841..87110.842 rows=0 loops=1)
>>    ->  Sort  (cost=109.44..113.19 rows=1500 width=112) (actual
>> time=25367.867..25367.930 rows=840 loops=1)
>> ```
>> The only thing I changed in the query was the date range.  It is actually
>> the CTE scan step inside the Sort block that is slower when no rows are
>> returned than when rows are returned.  It also only happens when all the
>> partitions are sequence scanned instead of being partition pruned.
>>
>> I'm still writing up a test case that can demo this without using
>> proprietary data.
>>
>
> After a bunch of experiments I can explain this now.  :-)
>
> I had a `limit` clause in my test CTE.  When sequence scanning a bunch of
> partitions, if the limit is reached, the subsequent partitions are marked
> with `never executed` and not scanned.  On the other hand, when no rows are
> found, all of the partitions are scanned.
>
> Therefore, with many millions of rows in the partitions, and being forced
> to sequence scan because I put the `at time zone` clause in the `where`,
> the case when rows are found is always noticeably faster than the case when
> rows aren't found as long as at least one partition hasn't been scanned yet
> when the limit is hit.
>
> I'm now satisfied this is a good thing, and will move on to other
> problems.  Thanks for hearing me out.  I was scratching my head for a while
> over that one.
>
>
>


-- 
-slava

Reply via email to