以Postgresql为主,再聊聊资料库 PostgreSQL Index 与 不等于

不等于 != , <>-- 1 有 pk 的情况create table it201010a (  id int not null primary key, val int not null);insert into it201010aselect generate_series(1,1e5)     , random() * 10000;-- 建立 indexcreate index on it201010a(val);commit;analyze it201010a;explain (analyze,verbose,timing,costs,buffers)select *  from it201010a where val <> 100;+-------------------------------------------------------------------------------------------------------------------+|                                                    QUERY PLAN                                                     |+-------------------------------------------------------------------------------------------------------------------+| Seq Scan on aki.it201010a  (cost=0.00..1693.00 rows=99990 width=8) (actual time=0.040..18.171 rows=99995 loops=1) ||   Output: id, val                                                                                                 ||   Filter: (it201010a.val <> 100)                                                                                  ||   Rows Removed by Filter: 5                                                                                       ||   Buffers: shared hit=443                                                                                         || Planning Time: 0.123 ms                                                                                           || Execution Time: 31.306 ms                                                                                         |+-------------------------------------------------------------------------------------------------------------------+-- 可以观察到,当过滤条件是不等于(<>)时, 不使用 indexexplain (analyze,timing,costs)select t1.*   from it201010a t1   left join it201010a t2     on (t1.id = t2.id    and t2.val = 100)  where t2.* is null;+---------------------------------------------------------------------------------------------------------------------------------------+|                                                              QUERY PLAN                                                               |+---------------------------------------------------------------------------------------------------------------------------------------+| Hash Left Join  (cost=40.24..1745.75 rows=500 width=8) (actual time=0.087..38.241 rows=99995 loops=1)                                 ||   Hash Cond: (t1.id = t2.id)                                                                                                          ||   Filter: (t2.* IS NULL)                                                                                                              ||   Rows Removed by Filter: 5                                                                                                           ||   ->  Seq Scan on it201010a t1  (cost=0.00..1443.00 rows=100000 width=8) (actual time=0.012..12.280 rows=100000 loops=1)              ||   ->  Hash  (cost=40.11..40.11 rows=10 width=36) (actual time=0.060..0.061 rows=5 loops=1)                                            ||         Buckets: 1024  Batches: 1  Memory Usage: 9kB                                                                                  ||         ->  Bitmap Heap Scan on it201010a t2  (cost=4.50..40.11 rows=10 width=36) (actual time=0.044..0.054 rows=5 loops=1)           ||               Recheck Cond: (val = 100)                                                                                               ||               Heap Blocks: exact=5                                                                                                    ||               ->  Bitmap Index Scan on it201010a_val_idx  (cost=0.00..4.49 rows=10 width=0) (actual time=0.031..0.032 rows=5 loops=1) ||                     Index Cond: (val = 100)                                                                                           || Planning Time: 0.371 ms                                                                                                               || Execution Time: 46.063 ms                                                                                                             |+---------------------------------------------------------------------------------------------------------------------------------------+-- 使用了 index.set enable_seqscan=off;  explain (analyze,timing,costs)select t1.*   from it201010a t1   left join it201010a t2     on (t1.id = t2.id    and t2.val = 100)  where t2.* is null;+-------------------------------------------------------------------------------------------------------------------------------------------------+|                                                                   QUERY PLAN                                                                    |+-------------------------------------------------------------------------------------------------------------------------------------------------+| Merge Left Join  (cost=40.57..3340.72 rows=500 width=8) (actual time=3.756..55.155 rows=99995 loops=1)                                          ||   Merge Cond: (t1.id = t2.id)                                                                                                                   ||   Filter: (t2.* IS NULL)                                                                                                                        ||   Rows Removed by Filter: 5                                                                                                                     ||   ->  Index Scan using it201010a_pkey on it201010a t1  (cost=0.29..3050.29 rows=100000 width=8) (actual time=0.054..27.778 rows=100000 loops=1) ||   ->  Sort  (cost=40.28..40.30 rows=10 width=36) (actual time=3.692..3.694 rows=5 loops=1)                                                      ||         Sort Key: t2.id                                                                                                                         ||         Sort Method: quicksort  Memory: 25kB                                                                                                    ||         ->  Bitmap Heap Scan on it201010a t2  (cost=4.50..40.11 rows=10 width=36) (actual time=0.252..0.360 rows=5 loops=1)                     ||               Recheck Cond: (val = 100)                                                                                                         ||               Heap Blocks: exact=5                                                                                                              ||               ->  Bitmap Index Scan on it201010a_val_idx  (cost=0.00..4.49 rows=10 width=0) (actual time=0.128..0.128 rows=5 loops=1)           ||                     Index Cond: (val = 100)                                                                                                     || Planning Time: 1.516 ms                                                                                                                         || Execution Time: 65.098 ms                                                                                                                       |+-------------------------------------------------------------------------------------------------------------------------------------------------+set enable_sort=off;  explain (analyze,timing,costs)select t1.*   from it201010a t1   left join it201010a t2     on (t1.id = t2.id    and t2.val = 100)  where t2.* is null; +-------------------------------------------------------------------------------------------------------------------------------------------------+|                                                                   QUERY PLAN                                                                    |+-------------------------------------------------------------------------------------------------------------------------------------------------+| Hash Left Join  (cost=40.53..3353.04 rows=500 width=8) (actual time=0.153..47.913 rows=99995 loops=1)                                           ||   Hash Cond: (t1.id = t2.id)                                                                                                                    ||   Filter: (t2.* IS NULL)                                                                                                                        ||   Rows Removed by Filter: 5                                                                                                                     ||   ->  Index Scan using it201010a_pkey on it201010a t1  (cost=0.29..3050.29 rows=100000 width=8) (actual time=0.019..21.066 rows=100000 loops=1) ||   ->  Hash  (cost=40.11..40.11 rows=10 width=36) (actual time=0.088..0.089 rows=5 loops=1)                                                      ||         Buckets: 1024  Batches: 1  Memory Usage: 9kB                                                                                            ||         ->  Bitmap Heap Scan on it201010a t2  (cost=4.50..40.11 rows=10 width=36) (actual time=0.032..0.043 rows=5 loops=1)                     ||               Recheck Cond: (val = 100)                                                                                                         ||               Heap Blocks: exact=5                                                                                                              ||               ->  Bitmap Index Scan on it201010a_val_idx  (cost=0.00..4.49 rows=10 width=0) (actual time=0.019..0.019 rows=5 loops=1)           ||                     Index Cond: (val = 100)                                                                                                     || Planning Time: 0.331 ms                                                                                                                         || Execution Time: 55.753 ms                                                                                                                       |+-------------------------------------------------------------------------------------------------------------------------------------------------+(14 rows)set enable_hashjoin=off;  explain (analyze,timing,costs)select t1.*   from it201010a t1   left join it201010a t2     on (t1.id = t2.id    and t2.val = 100)  where t2.* is null; +-------------------------------------------------------------------------------------------------------------------------------------------------+|                                                                   QUERY PLAN                                                                    |+-------------------------------------------------------------------------------------------------------------------------------------------------+| Merge Left Join  (cost=0.58..6600.71 rows=500 width=8) (actual time=4.255..61.982 rows=99995 loops=1)                                           ||   Merge Cond: (t1.id = t2.id)                                                                                                                   ||   Filter: (t2.* IS NULL)                                                                                                                        ||   Rows Removed by Filter: 5                                                                                                                     ||   ->  Index Scan using it201010a_pkey on it201010a t1  (cost=0.29..3050.29 rows=100000 width=8) (actual time=0.011..19.161 rows=100000 loops=1) ||   ->  Index Scan using it201010a_pkey on it201010a t2  (cost=0.29..3300.29 rows=10 width=36) (actual time=4.237..18.359 rows=5 loops=1)         ||         Filter: (val = 100)                                                                                                                     ||         Rows Removed by Filter: 99995                                                                                                           || Planning Time: 0.348 ms                                                                                                                         || Execution Time: 69.319 ms                                                                                                                       |+-------------------------------------------------------------------------------------------------------------------------------------------------+(10 rows)---------set enable_hashjoin=on;  set enable_sort=on; set enable_seqscan=on;---------- 2 没有 PK 的情况create table it201010b (  val int not null);insert into it201010bselect random() * 10000  from generate_series(1,1e5);  create index on it201010b(val);commit;analyze it201010b;-- 没有PK,我们可以用系统的ctidexplain (analyze,timing,costs)select t1.*   from it201010b t1   left join it201010b t2     on (t1.ctid = t2.ctid    and t2.val = 100)  where t2.* is null;+---------------------------------------------------------------------------------------------------------------------------------------+|                                                              QUERY PLAN                                                               |+---------------------------------------------------------------------------------------------------------------------------------------+| Hash Left Join  (cost=40.24..1858.34 rows=500 width=4) (actual time=0.196..39.142 rows=99991 loops=1)                                 ||   Hash Cond: (t1.ctid = t2.ctid)                                                                                                      ||   Filter: (t2.* IS NULL)                                                                                                              ||   Rows Removed by Filter: 9                                                                                                           ||   ->  Seq Scan on it201010b t1  (cost=0.00..1443.00 rows=100000 width=10) (actual time=0.018..16.793 rows=100000 loops=1)             ||   ->  Hash  (cost=40.11..40.11 rows=10 width=34) (actual time=0.117..0.118 rows=9 loops=1)                                            ||         Buckets: 1024  Batches: 1  Memory Usage: 9kB                                                                                  ||         ->  Bitmap Heap Scan on it201010b t2  (cost=4.50..40.11 rows=10 width=34) (actual time=0.091..0.108 rows=9 loops=1)           ||               Recheck Cond: (val = 100)                                                                                               ||               Heap Blocks: exact=9                                                                                                    ||               ->  Bitmap Index Scan on it201010b_val_idx  (cost=0.00..4.49 rows=10 width=0) (actual time=0.051..0.051 rows=9 loops=1) ||                     Index Cond: (val = 100)                                                                                           || Planning Time: 0.223 ms                                                                                                               || Execution Time: 47.081 ms                                                                                                             |+---------------------------------------------------------------------------------------------------------------------------------------+------------ 3 Array create table it201010c (  id int generated always as identity, arr int[] not null); do $$declare  i int;begin  for i in 1..10000 loop    insert into it201010c(arr)     select array_agg(round(random() * 1e3))       from generate_series(1,100);  end loop;end;$$ language plpgsql;commit;create index on it201010c using gin(arr);analyze it201010c;--explain (analyze,timing,costs)select *  from it201010c where not (arr @> array[1,2]); +--------------------------------------------------------------------------------------------------------------+|                                                  QUERY PLAN                                                  |+--------------------------------------------------------------------------------------------------------------+| Seq Scan on it201010c  (cost=0.00..714.00 rows=9913 width=428) (actual time=0.027..12.739 rows=9921 loops=1) ||   Filter: (NOT (arr @> '{1,2}'::integer[]))                                                                  ||   Rows Removed by Filter: 79                                                                                 || Planning Time: 3.535 ms                                                                                      || Execution Time: 13.665 ms                                                                                    |+--------------------------------------------------------------------------------------------------------------+-- 一样用 left join , null explain (analyze,timing,costs)select t1.*   from it201010c t1   left join it201010c t2     on (t1.id = t2.id    and t2.arr @> array[1,2]) where t2.* is null;+-----------------------------------------------------------------------------------------------------------------------------------------+|                                                               QUERY PLAN                                                                |+-----------------------------------------------------------------------------------------------------------------------------------------+| Hash Left Join  (cost=259.06..986.43 rows=50 width=428) (actual time=4.541..10.398 rows=9921 loops=1)                                   ||   Hash Cond: (t1.id = t2.id)                                                                                                            ||   Filter: (t2.* IS NULL)                                                                                                                ||   Rows Removed by Filter: 79                                                                                                            ||   ->  Seq Scan on it201010c t1  (cost=0.00..689.00 rows=10000 width=428) (actual time=0.008..2.415 rows=10000 loops=1)                  ||   ->  Hash  (cost=257.97..257.97 rows=87 width=456) (actual time=4.523..4.524 rows=79 loops=1)                                          ||         Buckets: 1024  Batches: 1  Memory Usage: 46kB                                                                                   ||         ->  Bitmap Heap Scan on it201010c t2  (cost=20.67..257.97 rows=87 width=456) (actual time=4.366..4.480 rows=79 loops=1)         ||               Recheck Cond: (arr @> '{1,2}'::integer[])                                                                                 ||               Heap Blocks: exact=76                                                                                                     ||               ->  Bitmap Index Scan on it201010c_arr_idx  (cost=0.00..20.65 rows=87 width=0) (actual time=4.325..4.326 rows=79 loops=1) ||                     Index Cond: (arr @> '{1,2}'::integer[])                                                                             || Planning Time: 3.118 ms                                                                                                                 || Execution Time: 11.486 ms                                                                                                               |+-----------------------------------------------------------------------------------------------------------------------------------------+-- 利用 not existsexplain (analyze,timing,costs)select t1.*   from it201010c t1  where not exists (       select 1          from it201010c t2         where t1.id = t2.id           and t2.arr @> array[1,2]);+-----------------------------------------------------------------------------------------------------------------------------------------+|                                                               QUERY PLAN                                                                |+-----------------------------------------------------------------------------------------------------------------------------------------+| Hash Anti Join  (cost=259.06..1073.54 rows=9913 width=428) (actual time=0.404..7.478 rows=9921 loops=1)                                 ||   Hash Cond: (t1.id = t2.id)                                                                                                            ||   ->  Seq Scan on it201010c t1  (cost=0.00..689.00 rows=10000 width=428) (actual time=0.008..2.913 rows=10000 loops=1)                  ||   ->  Hash  (cost=257.97..257.97 rows=87 width=4) (actual time=0.374..0.375 rows=79 loops=1)                                            ||         Buckets: 1024  Batches: 1  Memory Usage: 11kB                                                                                   ||         ->  Bitmap Heap Scan on it201010c t2  (cost=20.67..257.97 rows=87 width=4) (actual time=0.233..0.342 rows=79 loops=1)           ||               Recheck Cond: (arr @> '{1,2}'::integer[])                                                                                 ||               Heap Blocks: exact=76                                                                                                     ||               ->  Bitmap Index Scan on it201010c_arr_idx  (cost=0.00..20.65 rows=87 width=0) (actual time=0.215..0.215 rows=79 loops=1) ||                     Index Cond: (arr @> '{1,2}'::integer[])                                                                             || Planning Time: 0.259 ms                                                                                                                 || Execution Time: 8.959 ms                                                                                                                |+-----------------------------------------------------------------------------------------------------------------------------------------+没有PK时,一样可以利用 ctid, 在此就不赘述.今天我们探讨了 不等于的情况下, 怎样变化让优化器可以使用index.实际情况还要随着资料分布,index是否具有足够的鉴别性,适当使用 index.另外,也设定了几个参数,让大家可以观察执行计画的情况set enable_hashjoin=on;  set enable_sort=on; set enable_seqscan=on;也使用了 array 来探讨,并且使用了 not exists.希望能带给大家在使用时,有一些帮助.

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章