Re:Postgres Insider Terminology
by didgetmaster on Saturday November 05, 2022 @11:57AM
(#33482670)
When studying the internals of Postgres years ago, I learned that pages could greatly affect the disk space required to hold a table. If the page size was 8192 bytes (the default) and if the schema defined each row as holding 4097 bytes, then two rows would not fit within a single page. This would cause every row to be within its own page and would waste almost half of the space.
Re:Postgres Insider Terminology
by didgetmaster on Saturday November 05, 2022 @04:53PM
(#33485581)
I think it is true for every row-oriented database that stores all the values for a single row together within a fixed-sized structure. Columnar stores on the other hand may or may not do this.
I have built a database engine that is a columnar store. All the values for each column are stored together. This requires just about every query to fetch each row value separately, but it has proven to be incredibly fast. Queries on big tables run several times faster than on Postgres and it is also about 5x faster than on SQLite. https://www.youtube.com/watch?v=Va5ZqfwQXWI
Re:Postgres Insider Terminology
by didgetmaster on Sunday November 06, 2022 @10:19PM
(#33500707)
Mine is not. If a table has 4 columns (e.g. name, address, phone, email), then all the names are stored separately from the addresses. Likewise all the phone numbers are stored separately from the emails. The data is de-duped so it is incredibly easy to find out how many of each value is in each column (e.g. there are 1,234,567 rows in the table where name = 'John').
Re:Postgres Insider Terminology
by tomnipotent on Monday November 07, 2022 @08:02PM
(#33514737)
The downside is that a row requires random I/O across a larger number of pages, which also means more evictions from the in-memory buffer and worse cache efficiency. Apache Arrow, Parquet, Redshift, Bigtable/Spanner, Snowflake are all hybrid columnar, for example. You get good row data locality while still being able to exploit good SIMD/vector ops.
Re:Postgres Insider Terminology
by jeff-davis on Saturday November 05, 2022 @04:30PM
(#33485336)
What you are describing is called "internal fragmentation" and it's always a problem at some level in any system.
There are tons of ways to mitigate the problem including variable-length data, out-of-line storage, and compression. Postgres does those things, but I suppose there's always room to improve.
Best to just see how much storage a given table uses, and see if it's a problem.
Re:Postgres Insider Terminology
by Helmut10001 on Saturday November 05, 2022 @06:01PM
(#33486330)
Only slightly related, but the biggest increase in space I saw was after transitioning my 1.8 TB Postgres database to ZFS, which has compression turned on by default. Afterwards, the size needed was 310 GB, with no noticeable loss in speed.
Re:Postgres Insider Terminology
by Helmut10001 on Tuesday November 08, 2022 @09:48AM
(#33519536)
Yes. This is likely not the typical workload. Our PG database is only used in research, in "burst" situations - e.g. big batch jobs written to the DB (2 days 400 Million tuples) and read in big chunks (e.g. 400 Million tuples exported in 2 hours to CSV/Postgres FDW). ZFS is on spinning Rust (Sata 6GB), 6x8TB drives in a Raidz2 pool, the ZFS dataset is both compressed and encrypted. In Proxmox, I do not see I/O in any way limited during these burst writes/reads, the bottleneck is the CPU. However, the CPU was the bottleneck also before ZFS, so I cannot say how much impact the compression/encryption has. Other ZFS parameters are default (eg. filesystem recordsize is 128KB - lower values will yield better read speed, but less compression, and we were aiming for a lot of compression).
Likely no impact, but we use Postgres in Docker on unprivileged LXC, the `/data` directory is mounted from the LXC from the host ZFS pool. Since LXC runs all processes on the host, the performance impact is negligible (unlike, e.g. running this in a full VM).
I have the _feeling_ (not actually tested) that the Postgres database is faster with ZFS, since less data needs to be read, especially since we have a lot of sequential scans.
Re:Postgres Insider Terminology
by Helmut10001 on Tuesday November 08, 2022 @07:24PM
(#33526086)
Just looked it up [1]
> LZ4 is lossless compression algorithm, providing compression speed > 500 MB/s per core (>0.15 Bytes/cycle). It features an extremely fast decoder, with speed in multiple GB/s per core (~1 Byte/cycle).
Re:Postgres Insider Terminology
by to11mtm on Tuesday November 08, 2022 @04:10PM
(#33524343)
Yeah it's probably still true. It's also true of other DBs; There is usually a certain amount of overhead per-row on the page, or per-row.
So yeah, you have to either shrink to a size acceptable within padding, or pick a more appropriate page size, or play with some TOAST settings in the case of PG.
Re:Postgres Insider Terminology
by ialad on Saturday November 05, 2022 @12:55PM
(#33483225)
I was confused by the author's definition of a relation. They said that a single tuple is an "unary relation". They probably meant a single-tuple (1-tuple).
Removing the hyphen changes the meaning. https://en.wikipedia.org/wiki/Finitary_relation
Re:Postgres Insider Terminology
by layer8 on Saturday November 05, 2022 @06:42PM
(#33486712)
The author seems to have misunderstood Codd’s definition (which is just the usual definition for mathematical relations). An N-ary relation is an N-column table (in the idealized database model where a table is a mathematical set of rows, i.e. no duplicate rows).
Re:Postgres Insider Terminology
by hot_gril on Saturday November 05, 2022 @09:13PM
(#33487707)
One term that doesn't seem "insider" but kinda is: `timestamptz`, aka the thing you should always use instead of just `timestamp`. The full name is "timestamp with time zone," but contrary to what most people would assume, it doesn't store a time zone.
Re:Postgres Insider Terminology
by kurmouk on Saturday November 05, 2022 @10:36PM
(#33488291)
`timestamptz` stores the same data I believe. Only that when using `timestamptz` instead of `timestamp`, the server will convert the returned value based on the server time zone configuration. Both datatypes have 8 bytes.
Re:Postgres Insider Terminology
by Too on Sunday November 06, 2022 @01:43AM
(#33489896)
But normally you have a server between the user and the db, where you also prefer to keeps things as utc, while in memory. Then conversion to local time happens as the very last step in the presentation layer.
So unless you are using the sql result verbatim as presentation layer, is there any big benefit of this? On the contrary it seems like yet another moving part one could mess up and accidentally convert time where it shouldn’t?
Re:Postgres Insider Terminology
by hot_gril on Wednesday November 09, 2022 @05:38PM
(#33539091)
It's not what it looks like. Selecting either timestamp or timestamptz gives you a string representation in the database's configured local time zone, which your backend's Postgres driver will convert to whatever date representation (like `Date` in NodeJS). But timestamp leaves the time zone out of the string. Your Postgres driver assumes UTC in that case, which is a problem if your database is set to PST.
So with a PST database...
select now() as timestamptz; -- 2022-11-09T14:41:12.110+08
select now() as timestamp; -- 2022-11-09T14:41:12.110
You're right, this shouldn't be a thing. It's advisable to always set your Postgres config to UTC locale to eliminate the root of this nonsense, but that's not the default. So if your database is on PST, at least timestamptz will output strings that tell your code the correct time zone.
This is poorly explained in the official docs, btw. I think the only thing saving a lot of users is how AWS, GCP, etc all set their Postgres instances to UTC by default.
Re:Postgres Insider Terminology
by biztos on Saturday November 05, 2022 @10:54PM
(#33488363)
Per the docs[0], TIMESTAMP WITH TIME ZONE is preferred because it will automatically convert to/from the stored UTC to whatever your time zone is set to, in the config (by default) or within a query.
I think you also need it for converting input at specified time zones, which is more complicated than one might hope, using AT TIME ZONE.
So the point is about conversion, which is important, but I agree that it’s non-obvious that you need to store the source time zone separately if you ever want to retrieve it.
Super annoying.
Anyone know if this is still true?
* Except, maybe, toast, hot or compressed..
...that uses fixed sized pages.
sounds like could be one of those rule-proving exceptions, even if it is a big facebook project
I have built a database engine that is a columnar store. All the values for each column are stored together. This requires just about every query to fetch each row value separately, but it has proven to be incredibly fast. Queries on big tables run several times faster than on Postgres and it is also about 5x faster than on SQLite. https://www.youtube.com/watch?v=Va5ZqfwQXWI
There are tons of ways to mitigate the problem including variable-length data, out-of-line storage, and compression. Postgres does those things, but I suppose there's always room to improve.
Best to just see how much storage a given table uses, and see if it's a problem.
Likely no impact, but we use Postgres in Docker on unprivileged LXC, the `/data` directory is mounted from the LXC from the host ZFS pool. Since LXC runs all processes on the host, the performance impact is negligible (unlike, e.g. running this in a full VM).
I have the _feeling_ (not actually tested) that the Postgres database is faster with ZFS, since less data needs to be read, especially since we have a lot of sequential scans.
> LZ4 is lossless compression algorithm, providing compression speed > 500 MB/s per core (>0.15 Bytes/cycle). It features an extremely fast decoder, with speed in multiple GB/s per core (~1 Byte/cycle).
[1]: https://lz4.github.io/lz4/
So yeah, you have to either shrink to a size acceptable within padding, or pick a more appropriate page size, or play with some TOAST settings in the case of PG.
So unless you are using the sql result verbatim as presentation layer, is there any big benefit of this? On the contrary it seems like yet another moving part one could mess up and accidentally convert time where it shouldn’t?
So with a PST database...
select now() as timestamptz; -- 2022-11-09T14:41:12.110+08
select now() as timestamp; -- 2022-11-09T14:41:12.110
You're right, this shouldn't be a thing. It's advisable to always set your Postgres config to UTC locale to eliminate the root of this nonsense, but that's not the default. So if your database is on PST, at least timestamptz will output strings that tell your code the correct time zone.
This is poorly explained in the official docs, btw. I think the only thing saving a lot of users is how AWS, GCP, etc all set their Postgres instances to UTC by default.
I think you also need it for converting input at specified time zones, which is more complicated than one might hope, using AT TIME ZONE.
So the point is about conversion, which is important, but I agree that it’s non-obvious that you need to store the source time zone separately if you ever want to retrieve it.
[0]: https://www.postgresql.org/docs/current/datatype-datetime.ht...