Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 简单情况下的子查询性能_Sql_Postgresql - Fatal编程技术网

Sql 简单情况下的子查询性能

Sql 简单情况下的子查询性能,sql,postgresql,Sql,Postgresql,Postgresql 10-Ubuntu LTS最新版本-1CPU 2GB Ram-未安装其他软件 两个表,都有索引: 遵循(22条记录) 提示(2.5米记录) 需要0041毫秒 select tips.id from tips where tips.users_id in (2,3,4,5,6,8,79407,38463,42798,94150,76554,56777,71407,51788,4624,41079,13549,75920,18979,6078,26178,18316) Bi

Postgresql 10-Ubuntu LTS最新版本-1CPU 2GB Ram-未安装其他软件
两个表,都有索引:
遵循(22条记录)
提示(2.5米记录)

需要0041毫秒

select tips.id
from tips
where tips.users_id in (2,3,4,5,6,8,79407,38463,42798,94150,76554,56777,71407,51788,4624,41079,13549,75920,18979,6078,26178,18316) 

Bitmap Heap Scan on tips  (cost=101.72..2122.76 rows=556 width=8) (actual time=0.267..1.120 rows=597 loops=1)   
  Recheck Cond: (users_id = ANY ('{2,3,4,5,6,8,79407,38463,42798,94150,76554,56777,71407,51788,4624,41079,13549,75920,18979,6078,26178,18316}'::bigint[]))  
  Heap Blocks: exact=594    
  ->  Bitmap Index Scan on tips_idx_users_id01  (cost=0.00..101.58 rows=556 width=0) (actual time=0.188..0.188 rows=597 loops=1)    
        Index Cond: (users_id = ANY ('{2,3,4,5,6,8,79407,38463,42798,94150,76554,56777,71407,51788,4624,41079,13549,75920,18979,6078,26178,18316}'::bigint[]))  
Planning time: 0.210 ms 
Execution time: 1.193 ms 
耗时1.2毫秒(第一次运行时为4.7毫秒)

需要10433毫秒
定义:

CREATE TABLE public.follows (
  id             bigserial NOT NULL,
  users_id_from  bigint NOT NULL DEFAULT 0,
  users_id_to    bigint NOT NULL DEFAULT 0,
  has_accepted   boolean NOT NULL DEFAULT true,
  created_on     timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT followings_pkey
    PRIMARY KEY (id)
)

CREATE TABLE public.tips (
  id             bigserial NOT NULL,
  users_id       bigint NOT NULL,
  temp_id      bigint NOT NULL,
  first_seen    numeric(12,2) NOT NULL DEFAULT 0,
  created_on     timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
  expire_on_gmt  timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
  ip_from        inet NOT NULL DEFAULT '0.0.0.0'::inet,
  "type"         smallint NOT NULL DEFAULT 0,
  growth         numeric(8,1) NOT NULL DEFAULT 0.0,
  seen          boolean DEFAULT false,

  CONSTRAINT tips_pkey
    PRIMARY KEY (id)
)

CREATE INDEX tips_idx_users_id01
  ON public.tips
  (users_id);
我真的不明白为什么性能这么差,似乎服务器在幕后进行了连接…
任何帮助都将不胜感激

谢谢
佩雷斯

编辑-2018.10.9

尽管得到了公认的答案,但由于对Pavel Stehule的深入调查(见下文),世卫组织立即解决了问题,真正的问题是下表的统计数据不正确。真空分析解决了这个问题,现在两个queryes都运行得很快。

我正在尝试测试用例,我得到了完全不同的计划:

postgres=# explain analyze select * from foo where a in (select a from boo where b = 22); +------------------------------------------------------------------------------------------------------------------------------+ | QUERY PLAN | +------------------------------------------------------------------------------------------------------------------------------+ | Nested Loop (cost=16.19..7066.65 rows=2101 width=8) (actual time=0.444..11.667 rows=2713 loops=1) | | -> HashAggregate (cost=9.43..9.50 rows=7 width=4) (actual time=0.094..0.111 rows=9 loops=1) | | Group Key: boo.a | | -> Bitmap Heap Scan on boo (cost=4.33..9.42 rows=7 width=4) (actual time=0.048..0.071 rows=9 loops=1) | | Recheck Cond: (b = 22) | | Heap Blocks: exact=5 | | -> Bitmap Index Scan on boo_b_idx (cost=0.00..4.33 rows=7 width=0) (actual time=0.030..0.030 rows=9 loops=1) | | Index Cond: (b = 22) | | -> Bitmap Heap Scan on foo (cost=6.75..1005.16 rows=300 width=8) (actual time=0.256..1.143 rows=301 loops=9) | | Recheck Cond: (a = boo.a) | | Heap Blocks: exact=2678 | | -> Bitmap Index Scan on foo_a_idx (cost=0.00..6.68 rows=300 width=0) (actual time=0.145..0.145 rows=301 loops=9) | | Index Cond: (a = boo.a) | | Planning time: 0.971 ms | | Execution time: 12.105 ms ဠ | +------------------------------------------------------------------------------------------------------------------------------+ (15 rows) postgres=#解释分析选择*从foo中选择a,其中b=22(从boo中选择a); +------------------------------------------------------------------------------------------------------------------------------+ |查询计划| +------------------------------------------------------------------------------------------------------------------------------+ |嵌套循环(成本=16.19..7066.65行=2101宽度=8)(实际时间=0.444..11.667行=2713个循环=1)| |->HashAggregate(成本=9.43..9.50行=7宽度=4)(实际时间=0.094..0.111行=9循环=1)| |组键:boo.a| |->boo上的位图堆扫描(成本=4.33..9.42行=7宽度=4)(实际时间=0.048..0.071行=9个循环=1)| |复查条件:(b=22)| |堆块:精确=5| |->boo_b_idx上的位图索引扫描(成本=0.00..4.33行=7宽度=0)(实际时间=0.030..0.030行=9个循环=1)| |索引条件:(b=22)| |->foo上的位图堆扫描(成本=6.75..1005.16行=300宽度=8)(实际时间=0.256..1.143行=301循环=9)| |复查条件:(a=boo.a)| |堆块:精确=2678| |->foo_a_idx上的位图索引扫描(成本=0.00..6.68行=300宽度=0)(实际时间=0.145..0.145行=301循环=9)| |索引条件:(a=boo.a)| |计划时间:0.971毫秒| |执行时间:12.105毫秒ဠ | +------------------------------------------------------------------------------------------------------------------------------+ (15排) 虽然我惩罚了一些方法,但我得到了更好的计划-

postgres=# explain analyze select * from foo where a in (select a from boo where b = 22); +----------------------------------------------------------------------------------------------------------------------------+ | QUERY PLAN | +----------------------------------------------------------------------------------------------------------------------------+ | Nested Loop (cost=18.03..7894.11 rows=2101 width=8) (actual time=0.433..9.809 rows=2713 loops=1) | | -> Unique (cost=17.60..17.63 rows=7 width=4) (actual time=0.384..0.407 rows=9 loops=1) | | -> Sort (cost=17.60..17.62 rows=7 width=4) (actual time=0.383..0.388 rows=9 loops=1) | | Sort Key: boo.a | | Sort Method: quicksort Memory: 25kB | | -> Seq Scan on boo (cost=0.00..17.50 rows=7 width=4) (actual time=0.047..0.358 rows=9 loops=1) | | Filter: (b = 22) | | Rows Removed by Filter: 991 | | -> Index Scan using foo_a_idx on foo (cost=0.43..1122.21 rows=300 width=8) (actual time=0.023..0.874 rows=301 loops=9) | | Index Cond: (a = boo.a) | | Planning time: 0.957 ms | | Execution time: 10.399 ms | +----------------------------------------------------------------------------------------------------------------------------+ (12 rows) postgres=#解释分析选择*从foo中选择a,其中b=22(从boo中选择a); +----------------------------------------------------------------------------------------------------------------------------+ |查询计划| +----------------------------------------------------------------------------------------------------------------------------+ |嵌套循环(成本=18.03..7894.11行=2101宽度=8)(实际时间=0.433..9.809行=2713个循环=1)| |->唯一(成本=17.60..17.63行=7宽度=4)(实际时间=0.384..0.407行=9圈=1)| |->排序(成本=17.60..17.62行=7宽度=4)(实际时间=0.383..0.388行=9个循环=1)| |排序键:boo.a| |排序方法:快速排序内存:25kB| |->boo上的顺序扫描(成本=0.00..17.50行=7宽度=4)(实际时间=0.047..0.358行=9个循环=1)| |过滤器:(b=22)| |被筛选器删除的行:991| |->在foo上使用foo_a_idx进行索引扫描(成本=0.43..1122.21行=300宽度=8)(实际时间=0.023..0.874行=301循环=9)| |索引条件:(a=boo.a)| |计划时间:0.957毫秒| |执行时间:10.399毫秒| +----------------------------------------------------------------------------------------------------------------------------+ (12排) 在PostgreSQL 10.5上测试

在玩了一些游戏之后,我得到了:

+------------------------------------------------------------------------------------------------------------------------------------------------------+ | QUERY PLAN | +------------------------------------------------------------------------------------------------------------------------------------------------------+ | Gather (cost=1018.03..117733.71 rows=2101 width=8) (actual time=113.420..914.035 rows=2713 loops=1) | | Workers Planned: 2 | | Workers Launched: 2 | | -> Merge Semi Join (cost=18.03..116523.61 rows=875 width=8) (actual time=150.675..904.224 rows=904 loops=3) | | Merge Cond: (foo.a = boo.a) | | -> Parallel Index Scan using foo_a_idx on foo (cost=0.43..113510.99 rows=1250000 width=8) (actual time=0.136..800.463 rows=919564 loops=3) | | -> Sort (cost=17.60..17.62 rows=7 width=4) (actual time=0.347..0.357 rows=9 loops=3) | | Sort Key: boo.a | | Sort Method: quicksort Memory: 25kB | | -> Seq Scan on boo (cost=0.00..17.50 rows=7 width=4) (actual time=0.059..0.286 rows=9 loops=3) | | Filter: (b = 22) | | Rows Removed by Filter: 991 | | Planning time: 0.903 ms | | Execution time: 914.283 ms | +------------------------------------------------------------------------------------------------------------------------------------------------------+ (14 rows) +------------------------------------------------------------------------------------------------------------------------------------------------------+ |查询计划 postgres=# explain analyze select * from foo where a in (select a from boo where b = 22); +----------------------------------------------------------------------------------------------------------------------------+ | QUERY PLAN | +----------------------------------------------------------------------------------------------------------------------------+ | Nested Loop (cost=18.03..7894.11 rows=2101 width=8) (actual time=0.433..9.809 rows=2713 loops=1) | | -> Unique (cost=17.60..17.63 rows=7 width=4) (actual time=0.384..0.407 rows=9 loops=1) | | -> Sort (cost=17.60..17.62 rows=7 width=4) (actual time=0.383..0.388 rows=9 loops=1) | | Sort Key: boo.a | | Sort Method: quicksort Memory: 25kB | | -> Seq Scan on boo (cost=0.00..17.50 rows=7 width=4) (actual time=0.047..0.358 rows=9 loops=1) | | Filter: (b = 22) | | Rows Removed by Filter: 991 | | -> Index Scan using foo_a_idx on foo (cost=0.43..1122.21 rows=300 width=8) (actual time=0.023..0.874 rows=301 loops=9) | | Index Cond: (a = boo.a) | | Planning time: 0.957 ms | | Execution time: 10.399 ms | +----------------------------------------------------------------------------------------------------------------------------+ (12 rows) +------------------------------------------------------------------------------------------------------------------------------------------------------+ | QUERY PLAN | +------------------------------------------------------------------------------------------------------------------------------------------------------+ | Gather (cost=1018.03..117733.71 rows=2101 width=8) (actual time=113.420..914.035 rows=2713 loops=1) | | Workers Planned: 2 | | Workers Launched: 2 | | -> Merge Semi Join (cost=18.03..116523.61 rows=875 width=8) (actual time=150.675..904.224 rows=904 loops=3) | | Merge Cond: (foo.a = boo.a) | | -> Parallel Index Scan using foo_a_idx on foo (cost=0.43..113510.99 rows=1250000 width=8) (actual time=0.136..800.463 rows=919564 loops=3) | | -> Sort (cost=17.60..17.62 rows=7 width=4) (actual time=0.347..0.357 rows=9 loops=3) | | Sort Key: boo.a | | Sort Method: quicksort Memory: 25kB | | -> Seq Scan on boo (cost=0.00..17.50 rows=7 width=4) (actual time=0.059..0.286 rows=9 loops=3) | | Filter: (b = 22) | | Rows Removed by Filter: 991 | | Planning time: 0.903 ms | | Execution time: 914.283 ms | +------------------------------------------------------------------------------------------------------------------------------------------------------+ (14 rows)
select t.id
from tips t
where exists (select 1
              from follows f
              where f.users_id_from = 1 and f.users_id_to = t.users_id
             );
with f as (
      select users_id_to
      from follows
      where users_id_from = 1
     )
select t.id
from tips t
where t.users_id in (select f.users_id_to from f);
select t.id
from tips t join
     follows f
     on f.users_id_to = t.id
where f.users_id_from = 1