Note that there are some explanatory texts on larger screens.

plurals
  1. POPrimary key index not getting used
    primarykey
    data
    text
    <p>I created a table with composite primary key(of 3 columns) in postgresql. Default index not getting used, if use subsets in query which doesn't contains leading column. Which is not the case if we create index explicitly(index will be used for any subsets).</p> <p>By default postgres will create an index on the primary key. But as <a href="http://www.postgresql.org/docs/current/interactive/indexes-multicolumn.html" rel="nofollow">postgres document</a> says</p> <p><code>A multicolumn B-tree index can be used with query conditions that involve any subset of</code> <code>the index's columns, but the index is most efficient when there are constraints on the leading (leftmost) columns.</code></p> <p>If query doesn't include leading columns then also indexing will get used(if we create index explicitly), But indexing is not getting used when we are trying with subsets of default primary key index.</p> <p>Following are the schema and queries which not working with subsets.</p> <pre><code># \d client_data Table "public.client_data" Column | Type | Modifiers --------------------+-----------------------+----------- macaddr | character varying(64) | not null ts | bigint | not null interval | smallint | not null snr | smallint | not null rx_rate | bigint | tx_rate | bigint | rx_data | bigint | tx_data | bigint | Indexes: "client_data_pkey" PRIMARY KEY, btree (macaddr, ts, interval) </code></pre> <p>If we specify all the primary key columns then query planner will use indexing</p> <pre><code># explain analyze select count(*) from client_data where macaddr='a:b:c' and ts=346783556 and interval=5; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=8.60..8.61 rows=1 width=0) (actual time=0.040..0.041 rows=1 loops=1) -&gt; Index Scan using client_data_pkey on client_data (cost=0.00..8.59 rows=1 width=0) (actual time=0.037..0.037 rows=0 loops=1) Index Cond: (((macaddr)::text = 'a:b:c'::text) AND (ts = 346783556) AND ("interval" = 5)) Total runtime: 0.096 ms (4 rows) </code></pre> <p>But if we specify subsets, query planner won't use indexing</p> <pre><code># explain analyze select count(*) from client_data where ts=346783556; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Aggregate (cost=16176.01..16176.02 rows=1 width=0) (actual time=78.937..78.938 rows=1 loops=1) -&gt; Seq Scan on client_data (cost=0.00..16175.92 rows=36 width=0) (actual time=78.932..78.932 rows=0 loops=1) Filter: (ts = 346783556) Total runtime: 78.975 ms (4 rows) # explain analyze select count(*) from client_data where ts=346783556 and interval=5; QUERY PLAN ------------------------------------------------------------------------------------------------------------------ Aggregate (cost=17639.11..17639.12 rows=1 width=0) (actual time=78.815..78.815 rows=1 loops=1) -&gt; Seq Scan on client_data (cost=0.00..17639.11 rows=1 width=0) (actual time=78.810..78.810 rows=0 loops=1) Filter: ((ts = 346783556) AND ("interval" = 5)) Total runtime: 78.853 ms (4 rows) </code></pre> <p>But if we use leading column(macaddr) with either ts or interval, indexing will get used.</p> <pre><code># explain analyze select count(*) from client_data where macaddr='a' and ts=346783556; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=8.59..8.60 rows=1 width=0) (actual time=0.055..0.056 rows=1 loops=1) -&gt; Index Scan using client_data_pkey on client_data (cost=0.00..8.59 rows=1 width=0) (actual time=0.051..0.051 rows=0 loops=1) Index Cond: (((macaddr)::text = 'a'::text) AND (ts = 346783556)) Total runtime: 0.103 ms (4 rows) # explain analyze select count(*) from client_data where macaddr='a' and interval=56; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=56.15..56.16 rows=1 width=0) (actual time=0.021..0.022 rows=1 loops=1) -&gt; Index Scan using client_data_pkey on client_data (cost=0.00..56.15 rows=1 width=0) (actual time=0.017..0.017 rows=0 loops=1) Index Cond: (((macaddr)::text = 'a'::text) AND ("interval" = 56)) Total runtime: 0.055 ms (4 rows) </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload