简体   繁体   English

Postgres Left Join 和条件太慢

[英]Postgres Left Join with and condition too slow

I have two tables我有两张桌子

sleeps

SleepId睡眠标识符 SleepTime睡觉时间 WakeupTime唤醒时间
141b40f7-688b-43af-8266-3cc4612b8f98 141b40f7-688b-43af-8266-3cc4612b8f98 2021-11-25 22:27:30 2021-11-25 22:27:30 2021-11-25 22:16:30 2021-11-25 22:16:30
e91bd0f8-688b-43af-8266-dsc4612f8490 e91bd0f8-688b-43af-8266-dsc4612f8490 2021-11-24 22:27:30 2021-11-24 22:27:30 2021-11-24 22:16:30 2021-11-24 22:16:30

sleepupdates

SleepId睡眠标识符 SleepTime睡觉时间 WakeupTime唤醒时间
141b40f7-688b-43af-8266-3cc4612b8f98 141b40f7-688b-43af-8266-3cc4612b8f98 2021-11-25 22:27:30 2021-11-25 22:27:30 2021-11-25 22:16:30 2021-11-25 22:16:30

sleepupdates table might contain some SleepIds and if it does, I need to pick that WakeupTime (from sleepudates and not sleeps table). sleepupdates表可能包含一些 SleepIds,如果包含,我需要选择WakeupTime (来自sleepudates而不是sleeps表)。

I thought left join should work for this with coalesce but it looks like its taking too much time!我认为左连接应该通过合并来解决这个问题,但看起来它花费了太多时间!

It seems to scan the left table before it filter based on condition它似乎在根据条件过滤之前扫描左表

select s."SleepId", s."BedTime", s."SleepTime", coalesce(su."WakeupTime", s."WakeupTime") from sleeps s
left join sleepupdates su
on s."SleepId"=su."SleepId"
and s."SleepId"='141b40f7-688b-43af-8266-3cc4612b8f98

I need help in above query.我需要上述查询的帮助。

EXPLAIN ANALYZE

在此处输入图像描述

Text Format

explain (analyze,buffers,format text) select s."SleepId", s."BedTime", s."SleepTime", coalesce(su."WakeupTime", s."WakeupTime") from sleeps s
left join sleepupdates su
on s."SleepId"=su."SleepId"
and s."SleepId"='141b40f7-688b-43af-8266-3cc4612b8f98';
                                                           QUERY PLAN                                                           
--------------------------------------------------------------------------------------------------------------------------------
 Hash Right Join  (cost=123483.97..130997.74 rows=850932 width=40) (actual time=444.144..628.801 rows=852809 loops=1)
   Hash Cond: (su."SleepId" = s."SleepId")
   Join Filter: (s."SleepId" = '141b40f7-688b-43af-8266-3cc4612b8f98'::uuid)
   Rows Removed by Join Filter: 21396
   Buffers: shared hit=98037, temp read=4910 written=4848
   ->  Seq Scan on sleepupdates su  (cost=0.00..559.89 rows=21289 width=24) (actual time=0.005..2.806 rows=21396 loops=1)
         Buffers: shared hit=347
   ->  Hash  (cost=106199.32..106199.32 rows=850932 width=40) (actual time=438.068..438.068 rows=852809 loops=1)
         Buckets: 65536  Batches: 32  Memory Usage: 2067kB
         Buffers: shared hit=97690, temp written=4786
         ->  Seq Scan on sleeps s  (cost=0.00..106199.32 rows=850932 width=40) (actual time=0.007..263.471 rows=852809 loops=1)
               Buffers: shared hit=97690
 Planning time: 0.237 ms
 Execution time: 667.356 ms
(14 rows)

Indexes on sleepupdates

CREATE INDEX "sleepupdates_SleepId_idx"
    ON public.sleepupdates USING btree
    ("SleepId" ASC NULLS LAST)
    TABLESPACE pg_default;
-- Index: sleepupdates_SleepId_unique

-- DROP INDEX public."sleepupdates_SleepId_unique";

CREATE UNIQUE INDEX "sleepupdates_SleepId_unique"
    ON public.sleepupdates USING btree
    ("SleepId" ASC NULLS LAST, "Status" COLLATE pg_catalog."default" ASC NULLS LAST)
    TABLESPACE pg_default
    WHERE "Status" = 'PENDING'::text;
-- Index: sleepupdates_UserId_idx

-- DROP INDEX public."sleepupdates_UserId_idx";

CREATE INDEX "sleepupdates_UserId_idx"
    ON public.sleepupdates USING btree
    ("UserId" ASC NULLS LAST)
    TABLESPACE pg_default;

The SleepId is primary key in sleeps table SleepIdsleeps表中的主键

You are returning every row of sleeps.您正在返回每一行睡眠。 The s."SleepId"='141b40f7-688b-43af-8266-3cc4612b8f98 condition needs to be in a WHERE clause, not in the ON. s."SleepId"='141b40f7-688b-43af-8266-3cc4612b8f98条件需要在 WHERE 子句中,而不是在 ON 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM