Optimizer picking a poor plan for Serializable Transaction Isolation

Поиск
Список
Период
Сортировка
От Tyler Rockwood
Тема Optimizer picking a poor plan for Serializable Transaction Isolation
Дата
Msg-id CAO5aQPU-Ngp3VqA=tiQ8t5jM1HOfGh8SHvKZBLG=SOQq=Y-a1g@mail.gmail.com
обсуждение исходный текст
Ответы Re: Optimizer picking a poor plan for Serializable Transaction Isolation  (Tomas Vondra <tomas.vondra@enterprisedb.com>)
Список pgsql-bugs
We introduced our first query hint into our code today, and based on this wiki page I figured I report it as a bug.

Our table looks something like:

CREATE TABLE IF NOT EXISTS threads (  account_id VARCHAR(64),  group_id BIGINT,  thread_id VARCHAR(64),  "timestamp" BIGINT NOT NULL,  has_unread BOOLEAN NULL,  CONSTRAINT pk_threads PRIMARY KEY (account_id, group_id, thread_id)
);
CREATE UNIQUE INDEX threads_by_owner_group_time_id ON threads (account_id, group_id, "timestamp", thread_id);
CREATE UNIQUE INDEX threads_by_owner_group_unread_time_id ON threads (    account_id,    group_id,    has_unread,    "timestamp",    thread_id  );
We have a query that is a lookup - essentially this:
SELECT * FROM threads WHERE account_id = ? AND group_id = ? AND thread_id = ?;
Usually everything is fine and this does a query on the primary key index - but sometimes postgres decides to pick the threads_by_owner_group_unread_time_id index.

Picking the index is an issue because it ends up scanning essentially the whole index range for a given account_id and group_id. Due to the way upgrading predicate locks works - this almost always ends up locking the entire table if that group has enough threads. This causes a ton of contention in our database as this query happens for every incoming message (we have to book keep the has_unread column properly) and the predicate lock on the whole table interferes with every other active account's processing (we processing all events for a single account sequentially).

I think this index is being picked over the primary key because it's queried frequently and is likely to be cached or something. Anyways at any other isolation level this would be fine, but at serializability it ends up hurting throughput because we now retry a ton transactions unnecessarily.

I think there are two possible improvements here:

  1. Improving predicate locks to be smarter about handing singular lookups instead of treating this as a range scan. This has been discussed before here: https://www.postgresql.org/message-id/20110503064807.GB85173%40csail.mit.edu
  2. Pick the primary key in this case (which is what our hint does).

Happy to answer specific questions about this.

В списке pgsql-bugs по дате отправления:

Предыдущее
От: Japin Li
Дата:
Сообщение: Re: BUG #17409: Unable to alter data type of clustered column which is referenced by foreign key
Следующее
От: Daniel Shelepanov
Дата:
Сообщение: pg_visibility's pg_check_visible() yields false positive when working in parallel with autovacuum