PostgreSQL中的查询调优
我有一个17秒内运行的查询,但我想不出优化此查询的方法。非常需要一些帮助PostgreSQL中的查询调优,sql,postgresql,query-optimization,sql-tuning,Sql,Postgresql,Query Optimization,Sql Tuning,我有一个17秒内运行的查询,但我想不出优化此查询的方法。非常需要一些帮助 EXPLAIN ANALYSE CREATE materialized VIEW professores_fizeram_planejamentoTEST as SELECT unities.id as id_escola, unities.name as nome_escola, teachers.id as id_professor, teach
EXPLAIN ANALYSE
CREATE materialized VIEW professores_fizeram_planejamentoTEST as
SELECT unities.id as id_escola,
unities.name as nome_escola,
teachers.id as id_professor,
teachers.name as nome_professor,
datas.dia,
COALESCE((SELECT true
FROM lesson_plans
WHERE lesson_plans.teacher_id = teachers.id and
datas.dia between lesson_plans.start_at and lesson_plans.end_at
LIMIT 1), false) as criou_plano_aula,
COALESCE((select true
from content_records
where content_records.teacher_id = teachers.id and
content_records.record_date = datas.dia
limit 1), false) as criou_registro_conteudo
FROM (SELECT i::date as dia,
EXTRACT(year FROM i::date) as ano
FROM generate_series(date_trunc('year', now()), now(), '1 day'::INTERVAL) i
WHERE EXTRACT(dow from i::timestamp) in (1,2,3,4,5)) datas
JOIN (SELECT distinct teacher_id, classroom_id, YEAR
FROM teacher_discipline_classrooms) teacher_discipline_classrooms ON (teacher_discipline_classrooms.year = datas.ano)
JOIN classrooms on (classrooms.id = teacher_discipline_classrooms.classroom_id)
JOIN unities on (unities.id = classrooms.unity_id)
JOIN teachers on (teachers.id = teacher_discipline_classrooms.teacher_id)
WHERE NOT EXISTS(SELECT 1
FROM school_calendars
JOIN school_calendar_events on (school_calendar_events.school_calendar_id = school_calendars.id and
school_calendar_events.event_type = 'no_school' and
datas.dia between school_calendar_events.start_date and school_calendar_events.end_date)
WHERE school_calendars.unity_id = unities.id)
此查询返回以下分析
Nested Loop (cost=143.840..3721.540 rows=38 width=66) (actual time=1.923..17270.125 rows=171231 loops=1)
-> Nested Loop (cost=143.690..1523.510 rows=38 width=41) (actual time=1.744..5996.571 rows=171231 loops=1)
Join Filter: (NOT (delta 3))
Rows Removed by Join Filter: 15249
-> Nested Loop (cost=143.550..203.530 rows=76 width=16) (actual time=1.661..568.049 rows=186480 loops=1)
-> Hash Join (cost=143.270..165.450 rows=76 width=16) (actual time=1.651..183.740 rows=186660 loops=1)
Hash Cond: ((victor.juliet_seven)::double precision = echo_tango('quebec_four'::text, ((alpha_quebec_whiskey.alpha_quebec_whiskey)::date)::timestamp without time zone))
-> HashAggregate (cost=121.700..127.820 rows=612 width=12) (actual time=1.384..3.336 rows=2388 loops=1)
Group Key: victor.foxtrot_six, victor.oscar_kilo, victor.juliet_seven
-> Seq Scan on victor (cost=0.000..94.400 rows=3640 width=12) (actual time=0.004..0.563 rows=3640 loops=1)
-> Hash (cost=21.260..21.260 rows=25 width=8) (actual time=0.256..0.256 rows=180 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 16kB
-> Function Scan on xray_yankee alpha_quebec_whiskey (cost=0.010..21.260 rows=25 width=8) (actual time=0.081..0.195 rows=180 loops=1)
Filter: (echo_tango('papa'::text, (alpha_quebec_whiskey)::timestamp without time zone) = ANY ('oscar_seven_charlie'::double precision[]))
Rows Removed by Filter: 72
-> Index Scan using echo_victor on uniform (cost=0.280..0.490 rows=1 width=8) (actual time=0.001..0.002 rows=1 loops=186660)
Index Cond: (quebec_seven = victor.oscar_kilo)
-> Index Scan using golf on four (cost=0.140..0.160 rows=1 width=29) (actual time=0.001..0.001 rows=1 loops=186480)
Index Cond: (quebec_seven = uniform.xray_victor)
SubPlan
-> Nested Loop (cost=0.280..34.110 rows=2 width=0) (actual time=0.027..0.027 rows=0 loops=186480)
-> Seq Scan on seven (cost=0.000..1.990 rows=2 width=4) (actual time=0.003..0.008 rows=2 loops=186480)
Filter: (xray_victor = four.quebec_seven)
Rows Removed by Filter: 75
-> Index Scan using alpha_quebec_papa on two (cost=0.280..16.050 rows=1 width=4) (actual time=0.008..0.008 rows=0 loops=372960)
Index Cond: (zulu = seven.quebec_seven)
Filter: (((xray_delta)::text = 'oscar_seven_golf'::text) AND ((alpha_quebec_whiskey.alpha_quebec_whiskey)::date >= foxtrot_three) AND ((alpha_quebec_whiskey.alpha_quebec_whiskey)::date <= lima))
Rows Removed by Filter: 14
-> Index Scan using tango on romeo (cost=0.150..0.200 rows=1 width=29) (actual time=0.001..0.001 rows=1 loops=171231)
Index Cond: (quebec_seven = victor.foxtrot_six)
SubPlan
-> Limit (cost=0.000..20.600 rows=1 width=0) (actual time=0.048..0.048 rows=0 loops=171231)
-> Seq Scan on five (cost=0.000..20.600 rows=1 width=0) (actual time=0.045..0.045 rows=0 loops=171231)
Filter: ((foxtrot_six = romeo.quebec_seven) AND ((alpha_quebec_whiskey.alpha_quebec_whiskey)::date >= oscar_echo) AND ((alpha_quebec_whiskey.alpha_quebec_whiskey)::date <= xray_three))
Rows Removed by Filter: 246
SubPlan
-> Limit (cost=4.810..37.030 rows=1 width=0) (actual time=0.015..0.015 rows=0 loops=171231)
-> Bitmap Heap Scan on whiskey (cost=4.810..37.030 rows=1 width=0) (actual time=0.011..0.011 rows=0 loops=171231)
Recheck Cond: (foxtrot_six = romeo.quebec_seven)
Filter: (foxtrot_tango = (alpha_quebec_whiskey.alpha_quebec_whiskey)::date)
Rows Removed by Filter: 28
Heap Blocks: exact=258248
-> Bitmap Index Scan on juliet_bravo (cost=0.000..4.810 rows=70 width=0) (actual time=0.003..0.003 rows=37 loops=171231)
Index Cond: (foxtrot_six = romeo.quebec_seven)
嵌套循环(成本=143.840..3721.540行=38宽度=66)(实际时间=1.923..17270.125行=171231循环=1)
->嵌套循环(成本=143.690..1523.510行=38宽度=41)(实际时间=1.744..5996.571行=171231个循环=1)
联接筛选器:(非(增量3))
被联接筛选器删除的行:15249
->嵌套循环(成本=143.550..203.530行=76宽度=16)(实际时间=1.661..568.049行=186480个循环=1)
->散列联接(成本=143.270..165.450行=76宽度=16)(实际时间=1.651..183.740行=186660循环=1)
Hash Cond:((victor.juliet_seven)::双精度=回声探戈(‘魁北克四’::文本,((阿尔法魁北克威士忌。阿尔法魁北克威士忌)::日期)::无时区的时间戳))
->HashAggregate(成本=121.700..127.820行=612宽度=12)(实际时间=1.384..3.336行=2388个循环=1)
组键:维克托。狐步六号,维克托。奥斯卡。基洛,维克托。朱丽叶七号
->victor上的顺序扫描(成本=0.000..94.400行=3640宽度=12)(实际时间=0.004..0.563行=3640循环=1)
->散列(成本=21.260..21.260行=25宽度=8)(实际时间=0.256..0.256行=180循环=1)
存储桶:1024批:1内存使用量:16kB
->X射线功能扫描(成本=0.010..21.260行=25宽=8)(实际时间=0.081..0.195行=180圈=1)
过滤器:(echo_tango('papa'::text,(alpha_魁北克威士忌)::没有时区的时间戳)=ANY('oscar_seven_charlie'::双精度[])
被筛选器删除的行:72
->使用统一的echo_victor进行索引扫描(成本=0.280..0.490行=1宽度=8)(实际时间=0.001..0.002行=1圈=186660)
索引条件:(魁北克七号=维克多·奥斯卡·基洛)
->在四个上使用高尔夫进行索引扫描(成本=0.140..0.160行=1宽度=29)(实际时间=0.001..0.001行=1圈=186480)
索引条件:(魁北克七号=均匀X射线)
子计划
->嵌套循环(成本=0.280..34.110行=2宽度=0)(实际时间=0.027..0.027行=0循环=186480)
->七次扫描(成本=0.000..1.990行=2宽度=4)(实际时间=0.003..0.008行=2个循环=186480)
过滤器:(X射线=4。魁北克=7)
被筛选器删除的行:75
->使用alpha_quebec_papa对两个进行索引扫描(成本=0.280..16.050行=1宽度=4)(实际时间=0.008..0.008行=0循环=372960)
索引条件:(祖鲁=七。魁北克七)
过滤器:((X射线三角洲)::text='oscar_seven_golf'::text)和((阿尔法魁北克威士忌。阿尔法魁北克威士忌)::date>=狐步三)和((阿尔法魁北克威士忌。阿尔法魁北克威士忌)::在罗密欧上使用探戈进行日期索引扫描(成本=0.150..0.200行=1宽度=29)(实际时间=0.001..0.001行=1圈=171231)
索引条件:(魁北克七号=维克多·狐步六号)
子计划
->限制(成本=0.000..20.600行=1宽度=0)(实际时间=0.048..0.048行=0圈=171231)
->五次扫描的顺序(成本=0.000..20.600行=1宽度=0)(实际时间=0.045..0.045行=0循环=171231)
过滤器:((狐步六号=罗密欧·魁北克·七号)和((阿尔法·魁北克·阿尔法·魁北克·威士忌)::日期>=oscar·echo)和((阿尔法·魁北克·阿尔法·魁北克·威士忌)::日期限制(成本=4.810..37.030行=1宽度=0)(实际时间=0.015..0.015行=0圈=171231)
->威士忌上的位图堆扫描(成本=4.810..37.030行=1宽度=0)(实际时间=0.011..0.011行=0循环=171231)
复查条件:(狐步六号=罗密欧,魁北克七号)
过滤器:(狐步探戈=(阿尔法魁北克威士忌。阿尔法魁北克威士忌)::日期)
被筛选器删除的行:28
堆块:精确=258248
->juliet_bravo上的位图索引扫描(成本=0.000..4.810行=70宽度=0)(实际时间=0.003..0.003行=37圈=171231)
索引条件:(狐步六号=罗密欧,魁北克七号)
谢谢。这不是答案,而是一条不适合评论部分的评论。如果您想加快查询速度,请添加一些信息: 首先,请包括执行计划。这将告诉我们发生了什么 此外,请张贴:
课程计划的现有索引
content\u记录上的现有索引
教师纪律教室上的行
教师、学科、教室的现有索引
教室上的现有索引
单元上的现有索引
教师索引
学校日历上的现有索引
- 不,我们不会
- 清理查询(例如,添加别名并使用它们)
…可以由简单的合并((从课程计划中选择true,其中课程计划.teacher\u id=teachers.id,课程计划.start\u at和课程计划.end\u之间的datas.dia限制为1),false)为criou\u plano\u aula
EXISTS(子查询)
- 外部查询只引用{unities,teachers,datas},其余的表仅仅是连接表
- 如果查询计划中的预期值和观察值之间存在差异,那么您的统计数据是错误的
- generate_series()上的函数scan破坏了查询计划。最好使用材质日历表,它可以被索引和计数
- 始终在问题中添加调整参数和基数估计。这些不是细节