【发布时间】:2022-01-19 17:18:55
【问题描述】:
我有两张桌子
sleeps
| SleepId | SleepTime | WakeupTime |
|---|---|---|
| 141b40f7-688b-43af-8266-3cc4612b8f98 | 2021-11-25 22:27:30 | 2021-11-25 22:16:30 |
| e91bd0f8-688b-43af-8266-dsc4612f8490 | 2021-11-24 22:27:30 | 2021-11-24 22:16:30 |
sleepupdates
| SleepId | SleepTime | WakeupTime |
|---|---|---|
| 141b40f7-688b-43af-8266-3cc4612b8f98 | 2021-11-25 22:27:30 | 2021-11-25 22:16:30 |
sleepupdates 表可能包含一些 SleepId,如果包含,我需要选择该 WakeupTime(来自 sleepudates 而不是 sleeps 表)。
我认为 left join 应该可以通过 coalesce 解决这个问题,但它看起来需要太多时间!
它似乎在根据条件过滤之前扫描左表
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
我在上述查询中需要帮助。
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;
SleepId 是sleeps 表中的主键
【问题讨论】:
-
请edit您的问题并添加使用
explain (analyze, buffers, format text)生成的execution plan(不是只是一个“简单”解释)为formatted text,并确保保留计划的缩进。粘贴文本,然后将```放在计划前一行和计划后一行。还请包括所有索引的完整create index语句。 -
您添加的是图像,而不是格式化文本。
标签: sql postgresql left-join