Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indexing Null Values in PostgreSQL

I have a query of the form:

select m.id from mytable m left outer join othertable o on o.m_id = m.id     and o.col1 is not null and o.col2 is not null and o.col3 is not null where o.id is null 

The query returns a few hundred records, although the tables have millions of rows, and it takes forever to run (around an hour).

When I check my index statistics using:

select * from pg_stat_all_indexes where schemaname <> 'pg_catalog' and (indexrelname like 'othertable_%' or indexrelname like 'mytable_%') 

I see that only the index for othertable.m_id is being used, and that the indexes for col1..3 are not being used at all. Why is this?

I've read in a few places that PG has traditionally not been able to index NULL values. However, I've read this has supposedly changed since PG 8.3? I'm currently using PostgreSQL 8.4 on Ubuntu 10.04. Do I need to make a "partial" or "functional" index specifically to speed up IS NOT NULL queries, or is it already indexing NULLs and I'm just misunderstanding the problem?

like image 652
Cerin Avatar asked Aug 12 '10 13:08

Cerin


People also ask

Does PostgreSQL index NULL values?

PostgreSQL will not index NULL values. This is an important point. Because an index will never include NULL values, it cannot be used to satisfy the ORDER BY clause of a query that returns all rows in a table.

Can NULL be indexed?

By default, relational databases ignore NULL values (because the relational model says that NULL means "not present"). So, Index does not store NULL value, consequently if you have null condition in SQL statement, related index is ignored (by default).

How do you handle NULL values in PostgreSQL?

nullif also used with the coalesce function to handle the null values. PostgreSQL nullif function returns a null value if provided expressions are equal. If two expressions provided are equal, then it provides a null value; as a result, otherwise, it will return the first expression as a result.

Can we create index on nullable column in Postgres?

PostgreSQL treats NULL as distinct value, therefore, you can have multiple NULL values in a column with a UNIQUE index. When you define a primary key or a unique constraint for a table, PostgreSQL automatically creates a corresponding UNIQUE index.


1 Answers

You could try a partial index:

CREATE INDEX idx_partial ON othertable (m_id) WHERE (col1 is not null and col2 is not null and col3 is not null); 

From the docs: http://www.postgresql.org/docs/current/interactive/indexes-partial.html

like image 184
Matthew Wood Avatar answered Sep 22 '22 06:09

Matthew Wood