I have a table inheritance setup that might be simplified like this:
CREATE TABLE p (
id BIGSERIAL PRIMARY KEY,
type_id BIGINT,
approved BOOLEAN
);
CREATE INDEX ON p(approved);
CREATE TABLE a (
a_field VARCHAR,
PRIMARY KEY (id),
CHECK(type_id = 1::BIGINT)
) INHERITS (p);
CREATE TABLE b (
b_field INT,
PRIMARY KEY (id),
CHECK(type_id = 2::BIGINT)
) INHERITS (p);
CREATE INDEX ON b(approved);
CREATE TABLE c (
c_field NUMERIC,
PRIMARY KEY (id)
-- this table is missing the check constraint (for no good reason)
) INHERITS (p);
I now have a long-ish running transaction that locks table a
. While this is running, I observe queries on table b
that wait for that lock to be released, even though they are guaranteed to not use the data in a
. For example:
SELECT TRUE FROM p WHERE id = 12345 AND approved = false AND type_id = 2 LIMIT 1;
Running EXPLAIN
on that query shows something like this:
QUERY PLAN
----------------------------------------------------------------------------
Limit (cost= ...)
-> Result (cost= ...)
-> Append (cost= ...)
-> Seq Scan on p (cost= ...)
Filter: ((NOT approved) AND (id = 12345) AND (type_id = 2))
-> Index Scan using b_approved on b p (cost= ...)
Index Cond: (approved = false)
Filter: ((NOT approved) AND (id = 12345) AND (type_id = 2))
I am not sure if I’m reading that correctly, but it appears to me that the query planner thinks it needs to go through the parent table because it does not know whether table c
might contain the rows it’s looking for. In reality, there’s more than one table (in fact, a couple of dozens) like c
, which lack the CHECK constraint, so it seems plausible to me that the planner thinks a Seq Scan on the parent might be the most efficient route.
Will I avoid locks on a
interfering with an unrelated (in terms of data) query on b
if I add proper check constraints to c
(the c-like tables all could get one, it would be some work, though)?
Are there other remarks on this kind of setup with regard to locking?
Note that one of the reasons why this partitioning exists is that the application running the queries has parts that are agnostic to what child table it is dealing with, hence the query shown goes to p
. Additionally, such a query might affect a small number of tables (3-5) instead of just b
, i. e., the query plan shows additional Index Scan
lines like the one for b
shown here.