1

Let's say we have table like this:

CREATE TABLE user_device_infos
(
  id integer NOT NULL DEFAULT nextval('user_device_infos_id_seq1'::regclass),
  user_id integer,
  data jsonb,
  created_at timestamp without time zone NOT NULL,
  updated_at timestamp without time zone NOT NULL,
  CONSTRAINT user_device_infos_pkey PRIMARY KEY (id),
  CONSTRAINT fk_rails_e4001464ba FOREIGN KEY (user_id)
      REFERENCES public.users (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

CREATE INDEX index_user_device_infos_imei_user_id
  ON public.user_device_infos
  USING btree
  (((data -> 'Network'::text) ->> 'IMEI No'::text) COLLATE pg_catalog."default", user_id);

CREATE INDEX index_user_device_infos_on_user_id
  ON public.user_device_infos
  USING btree
  (user_id);

Now i try to select user_id from first device with the same imei:

SELECT  user_id FROM user_device_infos WHERE (data->'Network'->>'IMEI No' = 'xxxx') order by id LIMIT 1

This query takes 5 seconds on my table ( 152000 entries ) But if i write

SELECT  user_id FROM user_device_infos WHERE (data->'Network'->>'IMEI No' = 'xxxx') order by created_at asc LIMIT 1
SELECT  user_id FROM user_device_infos WHERE (data->'Network'->>'IMEI No' = 'xxxx') order by created_at desc LIMIT 1

query takes less then 1 ms. Why this query i so much faster then first variant ? There are no indexes on created at, and id is primary key

Upd

As suggested in comments, i ran explain analyze, but still don't understand what is wrong with "order by id" query. Sorry, i am not a sql-dev

# explain analyze SELECT  user_id FROM user_device_infos WHERE (data->'Network'->>'IMEI No' = 'xxxx') order by id LIMIT 1;
                                                                         QUERY PLAN                                                                          
-------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.42..416.84 rows=1 width=8) (actual time=5289.784..5289.784 rows=0 loops=1)
   ->  Index Scan using user_device_infos_pkey on user_device_infos  (cost=0.42..316483.14 rows=760 width=8) (actual time=5289.782..5289.782 rows=0 loops=1)
         Filter: (((data -> 'Network'::text) ->> 'IMEI No'::text) = 'xxxx'::text)
         Rows Removed by Filter: 152437
 Planning time: 0.153 ms
 Execution time: 5289.817 ms
(6 rows)
# explain analyze SELECT  user_id FROM user_device_infos WHERE (data->'Network'->>'IMEI No' = 'xxxx') order by created_at LIMIT 1;
                                                                         QUERY PLAN                                                                         
------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=2823.73..2823.74 rows=1 width=12) (actual time=0.064..0.064 rows=0 loops=1)
   ->  Sort  (cost=2823.73..2825.63 rows=760 width=12) (actual time=0.062..0.062 rows=0 loops=1)
         Sort Key: created_at
         Sort Method: quicksort  Memory: 25kB
         ->  Bitmap Heap Scan on user_device_infos  (cost=22.31..2819.93 rows=760 width=12) (actual time=0.039..0.039 rows=0 loops=1)
               Recheck Cond: (((data -> 'Network'::text) ->> 'IMEI No'::text) = 'xxxx'::text)
               ->  Bitmap Index Scan on index_user_device_infos_imei_user_id  (cost=0.00..22.12 rows=760 width=0) (actual time=0.037..0.037 rows=0 loops=1)
                     Index Cond: (((data -> 'Network'::text) ->> 'IMEI No'::text) = 'xxxx'::text)
 Planning time: 0.144 ms
 Execution time: 0.092 ms
(10 rows)
Yegor Razumovsky
  • 902
  • 2
  • 9
  • 26

0 Answers0