I have a boolean column that will be false for>99.9% of the rows. I need to efficiently fetch all rows where that column is true.
What's the best option? Creating an index on the column? Creating a partial index where the column is true? But I don't know what columns the partial index would / should hold.
This doesn't parse, but is there any way to do something like: CREATE INDEX mytable_cond ON mytable () WHERE cond = TRUE;
? Where the index holds literally zero columns?
-
Partial indexMcNets– McNets2020年04月04日 22:07:03 +00:00Commented Apr 4, 2020 at 22:07
-
Yes, but on what rows? What rows do I put in ( )?lurf jurv– lurf jurv2020年04月04日 22:10:42 +00:00Commented Apr 4, 2020 at 22:10
-
What other columns do you have in the table? Will you ever restrict on those too? How many rows are true?Colin 't Hart– Colin 't Hart2020年04月04日 22:34:46 +00:00Commented Apr 4, 2020 at 22:34
-
No, I only need to fetch where this one boolean column is true. There are many other columns. I have some other complicated indexes for the other common query. Less than one in a thousand rows will have this column as true.lurf jurv– lurf jurv2020年04月04日 23:16:48 +00:00Commented Apr 4, 2020 at 23:16
1 Answer 1
You are saying "rows" where I think you mean "columns".
It is not legal to specify an empty list of columns in an index. Just pick a column, preferably one with a short data type. If nothing else, just repeat the same column in both places.
CREATE INDEX mytable_cond ON mytable (cond) WHERE cond = TRUE;
Be careful how you formulate our index and queries. A cond = true
query cannot use a partial index defined where cond is true
and vice versa, those are not considered equivalent operations.
-
Thanks, you are correct, I have edited my question to say "columns". I will just make a partial index like you say on the column itself, where the value is true.lurf jurv– lurf jurv2020年04月05日 00:39:05 +00:00Commented Apr 5, 2020 at 0:39
-
@lurfjurv: I would probably include the primary key or some other frequently used columns into the index.user1822– user18222020年04月05日 06:08:36 +00:00Commented Apr 5, 2020 at 6:08
-
I'm curious; why? Is it so that the query can become index-only if I'm only fetching a few of the columns? Or another reason?lurf jurv– lurf jurv2020年04月05日 06:12:38 +00:00Commented Apr 5, 2020 at 6:12
-
1You don't have to use columns as the key fields of your index; you can use expressions (including literal constants!) as well. I did this for one of my tables:
CREATE INDEX cash_flow_items_unpaid_idx ON cash_flow_items ((true)) WHERE paid IS DISTINCT FROM accrued;
. (Most of mycash_flow_items
rows havepaid = accrued
, but I want to index the rows where that is not the case.) The doubled parentheses aroundtrue
are necessary to get the parser to parse it as an expression rather than as a column name.Matt Whitlock– Matt Whitlock2025年01月27日 09:07:48 +00:00Commented Jan 27 at 9:07