I have a table articles
:
Table "articles"
Column | Type | Modifiers | Storage | Stats target | Description
----------------+-----------------------------+----------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('articles_id_seq'::regclass) | plain | |
user_id | integer | | plain | |
title | character varying(255) | | extended | |
author | character varying(255) | | extended | |
body | text | default '--- [] +| extended | |
| | '::text | | |
created_at | timestamp without time zone | | plain | |
updated_at | timestamp without time zone | | plain | |
published_date | timestamp without time zone | | plain | |
Indexes:
"articles_pkey" PRIMARY KEY, btree (id)
"index_articles_on_published_date" btree (published_date)
"index_rents_on_user_id" btree (user_id)
"index_articles_on_user_id_and_published_date" btree (user_id, published_date)
We're on Postgres 9.4.4. The machine has 3.5 GB of memory and 150 GB of disk space on an SSD.
Note: The 'published_date' is always rounded, by the application, to the nearest date. All hours/minutes/seconds are always 00. Legacy. Needs fixed. Etc.
This table has hundreds of millions of articles. The table receives a great deal of read queries from (as many as 16) concurrent processes performing the following queries as quickly as our system will respond:
a count of the total number of articles
SELECT COUNT(*) FROM articles;
a select of all articles published for a given user
SELECT * FROM articles WHERE user_id = $1;
a select of the most recently published article for a given user
SELECT * FROM articles WHERE user_id = $1 ORDER BY published_date DESC LIMIT 1;
I am finding that, with a large number of workers, these queries are quite slow. (At peak load, the first takes minutes to complete; the other two are on the order of 10 seconds.) In particular, it seems that queries are being enqueued.
The question
In the abstract, do tables with only fixed width values perform read queries better than those with varying widths? (Pretend disk space isn't an issue.) In my case, I'm wondering if I would see a performance improvement if I were to extract the 'body' text field to a separate table and transform the character varying fields into fixed width character fields.
I admit the question is a bit cargo cult-y. I simply don't know enough about the internals of the Postgres DB engine to construct an informed hypothesis. I do intend to perform real experiments with different schemas and configurations but I'd like to have a solid mental model of how Postgres actually works before I go much further.
Related question
Where can I learn more about the internals of the Postgres DB engine? I've Googled variations of the above question with little success. What are the correct terms to use for this search? Does this level of documentation exist only in source and the minds of Postgres DBAs? I also humbly invite the suggestion of good books on the topic.
explain (buffers, analyze)
for the queries, please. At least two runs each, one "cold" when it hasn't been done in a while, one "hot" just after already run.TOAST
tables it can be faster to read the rest of the table.TOAST
. Not touching theTOAST
table at all would make a noticeable difference. One more reason to avoidSELECT *
if not all columns are needed.explain (buffers, analyze)
, but I intended for this question to be a more general "theory" or "basics of postgres performance" question. The above table is (as you may have inferred) not the actual table our application uses. If you still think it's pertinent, let me know and I'll edit the question.