我正在使用PostgreSQL 9.4.4
视图V_OpenCourse_WithTC
SELECT x1.id,
(x1.data ->> 'subject_id'::text)::bigint AS subject_id,
x2.data ->> 'program_session'::text AS program_session,
(x2.data ->> 'semester_id'::text)::bigint AS semester_id,
(x2.data ->> 'curriculum_id'::text)::bigint AS curriculum_id,
(x3.data ->> 'major_id'::text)::bigint AS major_id
FROM open_courses x1
JOIN trimester_courses x2 ON ((x1.data ->> 'trimester_course_id'::text)::bigint) = x2.id
JOIN tags x3 ON ((x2.data ->> 'curriculum_id'::text)::bigint) = x3.id AND (x3.data ->> 'type'::text) = 'curriculum'::text
WHERE x1.is_deleted = false;
从该视图中选择=快速
explain analyze SELECT * FROM V_OpenCourse_WithTC;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
Hash Join (cost=92.89..251.57 rows=18 width=382) (actual time=2.086..9.478 rows=3832 loops=1)
Hash Cond: (((x1.data ->> 'trimester_course_id'::text))::bigint = x2.id)
-> Seq Scan on open_courses x1 (cost=0.00..128.00 rows=3991 width=105) (actual time=0.007..0.815 rows=3991 loops=1)
Filter: (NOT is_deleted)
Rows Removed by Filter: 9
-> Hash (cost=92.81..92.81 rows=6 width=285) (actual time=2.067..2.067 rows=1405 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 558kB
-> Hash Join (cost=31.16..92.81 rows=6 width=285) (actual time=0.297..1.508 rows=1405 loops=1)
Hash Cond: (((x2.data ->> 'curriculum_id'::text))::bigint = x3.id)
-> Seq Scan on trimester_courses x2 (cost=0.00..51.05 rows=1405 width=131) (actual time=0.003..0.160 rows=1405 loops=1)
-> Hash (cost=31.12..31.12 rows=3 width=162) (actual time=0.287..0.287 rows=101 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 25kB
-> Seq Scan on tags x3 (cost=0.00..31.12 rows=3 width=162) (actual time=0.168..0.264 rows=101 loops=1)
Filter: ((data ->> 'type'::text) = 'curriculum'::text)
Rows Removed by Filter: 574
Planning time: 0.226 ms
Execution time: 9.655 ms
(17 rows)
从主表中选择=快速
explain analyze
SELECT id, data->>'open_course_id' oc_id
FROM student_credits
WHERE (data->>'student_id')::BIGINT = '5500'
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Seq Scan on student_credits (cost=0.00..14631.51 rows=910 width=396) (actual time=37.330..71.647 rows=33 loops=1)
Filter: (((data ->> 'student_id'::text))::bigint = 5500::bigint)
Rows Removed by Filter: 181979
Planning time: 0.043 ms
Execution time: 71.665 ms
explain analyze
SELECT x1.id
FROM student_credits x1
JOIN course_classes x2
ON (x1.data->>'course_class_id')::BIGINT = x2.id
JOIN open_courses x3
ON (x2.data->>'open_course_id')::BIGINT = x3.id
JOIN trimester_courses x4
ON (x3.data->>'trimester_course_id')::BIGINT = x4.id
WHERE (x1.data->>'student_id')::BIGINT = '5500'
AND x4.data->>'semester_id' = '53'
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------
Hash Join (cost=1541.70..16177.81 rows=5 width=8) (actual time=80.254..80.254 rows=0 loops=1)
Hash Cond: (((x1.data ->> 'course_class_id'::text))::bigint = x2.id)
-> Seq Scan on student_credits x1 (cost=0.00..14629.24 rows=910 width=396) (actual time=25.195..72.745 rows=33 loops=1)
Filter: (((data ->> 'student_id'::text))::bigint = 5500::bigint)
Rows Removed by Filter: 181979
-> Hash (cost=1541.08..1541.08 rows=50 width=8) (actual time=7.473..7.473 rows=814 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 32kB
-> Hash Join (cost=216.61..1541.08 rows=50 width=8) (actual time=2.050..7.372 rows=814 loops=1)
Hash Cond: (((x2.data ->> 'open_course_id'::text))::bigint = x3.id)
-> Seq Scan on course_classes x2 (cost=0.00..1248.55 rows=10055 width=653) (actual time=0.002..0.946 rows=10055 loops=1)
-> Hash (cost=216.36..216.36 rows=20 width=8) (actual time=2.038..2.038 rows=410 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 17kB
-> Hash Join (cost=58.16..216.36 rows=20 width=8) (actual time=0.463..1.992 rows=410 loops=1)
Hash Cond: (((x3.data ->> 'trimester_course_id'::text))::bigint = x4.id)
-> Seq Scan on open_courses x3 (cost=0.00..128.00 rows=4000 width=105) (actual time=0.002..0.315 rows=4000 loops=1)
-> Hash (cost=58.08..58.08 rows=7 width=8) (actual time=0.447..0.447 rows=142 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 6kB
-> Seq Scan on trimester_courses x4 (cost=0.00..58.08 rows=7 width=8) (actual time=0.011..0.431 rows=142 loops=1)
Filter: ((data ->> 'semester_id'::text) = '53'::text)
Rows Removed by Filter: 1263
Planning time: 0.234 ms
Execution time: 80.296 ms
(22 rows)
explain analyze
SELECT x1.id
FROM student_credits x1
WHERE (x1.data->>'student_id')::BIGINT = '5500'
AND (x1.data->>'open_course_id')::BIGINT IN (
SELECT id
FROM V_OpenCourse_WithTC
WHERE semester_id = '53'
)
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop Semi Join (cost=65.19..14905.52 rows=455 width=8) (actual time=87.144..87.144 rows=0 loops=1)
Join Filter: (((x1.data ->> 'open_course_id'::text))::bigint = x1_1.id)
Rows Removed by Join Filter: 13233
-> Seq Scan on student_credits x1 (cost=0.00..14629.24 rows=910 width=396) (actual time=23.892..71.475 rows=33 loops=1)
Filter: (((data ->> 'student_id'::text))::bigint = 5500::bigint)
Rows Removed by Filter: 181979
-> Materialize (cost=65.19..255.81 rows=1 width=8) (actual time=0.021..0.420 rows=401 loops=33)
-> Nested Loop (cost=65.19..255.80 rows=1 width=8) (actual time=0.680..13.356 rows=401 loops=1)
Join Filter: (((x2.data ->> 'curriculum_id'::text))::bigint = x3.id)
Rows Removed by Join Filter: 40100
-> Hash Join (cost=65.19..223.32 rows=20 width=131) (actual time=0.501..2.150 rows=401 loops=1)
Hash Cond: (((x1_1.data ->> 'trimester_course_id'::text))::bigint = x2.id)
-> Seq Scan on open_courses x1_1 (cost=0.00..128.00 rows=3991 width=105) (actual time=0.006..0.580 rows=3991 loops=1)
Filter: (NOT is_deleted)
Rows Removed by Filter: 9
-> Hash (cost=65.10..65.10 rows=7 width=131) (actual time=0.481..0.481 rows=142 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 23kB
-> Seq Scan on trimester_courses x2 (cost=0.00..65.10 rows=7 width=131) (actual time=0.009..0.454 rows=142 loops=1)
Filter: (((data ->> 'semester_id'::text))::bigint = 53::bigint)
Rows Removed by Filter: 1263
-> Materialize (cost=0.00..31.14 rows=3 width=8) (actual time=0.000..0.004 rows=101 loops=401)
-> Seq Scan on tags x3 (cost=0.00..31.12 rows=3 width=8) (actual time=0.114..0.208 rows=101 loops=1)
Filter: ((data ->> 'type'::text) = 'curriculum'::text)
Rows Removed by Filter: 574
Planning time: 0.320 ms
Execution time: 87.188 ms
(26 rows)
explain analyze
SELECT x1.id
FROM student_credits x1
, V_OpenCourse_WithTC x2
WHERE (x1.data->>'student_id')::BIGINT = '5500'
AND x2.semester_id = '53'
AND (x1.data->>'open_course_id')::BIGINT = x2.id
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=177.89..14951.55 rows=1 width=8) (actual time=10155.277..10155.277 rows=0 loops=1)
Join Filter: (((x1_1.data ->> 'trimester_course_id'::text))::bigint = x2.id)
-> Nested Loop (cost=0.00..96.70 rows=1 width=8) (actual time=0.221..5.487 rows=142 loops=1)
Join Filter: (((x2.data ->> 'curriculum_id'::text))::bigint = x3.id)
Rows Removed by Join Filter: 14200
-> Seq Scan on trimester_courses x2 (cost=0.00..65.10 rows=7 width=131) (actual time=0.013..0.637 rows=142 loops=1)
Filter: (((data ->> 'semester_id'::text))::bigint = 53::bigint)
Rows Removed by Filter: 1263
-> Materialize (cost=0.00..31.14 rows=3 width=8) (actual time=0.001..0.006 rows=101 loops=142)
-> Seq Scan on tags x3 (cost=0.00..31.12 rows=3 width=8) (actual time=0.146..0.225 rows=101 loops=1)
Filter: ((data ->> 'type'::text) = 'curriculum'::text)
Rows Removed by Filter: 574
-> Hash Join (cost=177.89..14836.68 rows=908 width=105) (actual time=71.475..71.475 rows=0 loops=142)
Hash Cond: (((x1.data ->> 'open_course_id'::text))::bigint = x1_1.id)
-> Seq Scan on student_credits x1 (cost=0.00..14629.24 rows=910 width=396) (actual time=36.517..71.458 rows=33 loops=142)
Filter: (((data ->> 'student_id'::text))::bigint = 5500::bigint)
Rows Removed by Filter: 181979
-> Hash (cost=128.00..128.00 rows=3991 width=105) (actual time=1.428..1.428 rows=3991 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 549kB
-> Seq Scan on open_courses x1_1 (cost=0.00..128.00 rows=3991 width=105) (actual time=0.005..0.736 rows=3991 loops=1)
Filter: (NOT is_deleted)
Rows Removed by Filter: 9
Planning time: 0.309 ms
Execution time: 10155.321 ms
(24 rows)
explain analyze
SELECT x1.id
FROM student_credits x1
JOIN (
SELECT * FROM V_OpenCourse_WithTC
WHERE semester_id = '53'
) x2
ON (x1.data->>'open_course_id')::BIGINT = x2.id
WHERE (x1.data->>'student_id')::BIGINT = '5500'
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=177.89..14951.55 rows=1 width=8) (actual time=10229.667..10229.667 rows=0 loops=1)
Join Filter: (((x1_1.data ->> 'trimester_course_id'::text))::bigint = x2.id)
-> Nested Loop (cost=0.00..96.70 rows=1 width=8) (actual time=0.218..5.623 rows=142 loops=1)
Join Filter: (((x2.data ->> 'curriculum_id'::text))::bigint = x3.id)
Rows Removed by Join Filter: 14200
-> Seq Scan on trimester_courses x2 (cost=0.00..65.10 rows=7 width=131) (actual time=0.014..0.705 rows=142 loops=1)
Filter: (((data ->> 'semester_id'::text))::bigint = 53::bigint)
Rows Removed by Filter: 1263
-> Materialize (cost=0.00..31.14 rows=3 width=8) (actual time=0.001..0.006 rows=101 loops=142)
-> Seq Scan on tags x3 (cost=0.00..31.12 rows=3 width=8) (actual time=0.142..0.229 rows=101 loops=1)
Filter: ((data ->> 'type'::text) = 'curriculum'::text)
Rows Removed by Filter: 574
-> Hash Join (cost=177.89..14836.68 rows=908 width=105) (actual time=71.998..71.998 rows=0 loops=142)
Hash Cond: (((x1.data ->> 'open_course_id'::text))::bigint = x1_1.id)
-> Seq Scan on student_credits x1 (cost=0.00..14629.24 rows=910 width=396) (actual time=36.812..71.981 rows=33 loops=142)
Filter: (((data ->> 'student_id'::text))::bigint = 5500::bigint)
Rows Removed by Filter: 181979
-> Hash (cost=128.00..128.00 rows=3991 width=105) (actual time=1.401..1.401 rows=3991 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 549kB
-> Seq Scan on open_courses x1_1 (cost=0.00..128.00 rows=3991 width=105) (actual time=0.005..0.681 rows=3991 loops=1)
Filter: (NOT is_deleted)
Rows Removed by Filter: 9
Planning time: 0.313 ms
Execution time: 10229.720 ms
(24 rows)
explain analyze
SELECT x1.id
FROM (
SELECT id, data->>'open_course_id' oc_id
FROM student_credits
WHERE (data->>'student_id')::BIGINT = '5500'
) x1
JOIN (
SELECT id FROM V_OpenCourse_WithTC
WHERE semester_id = '53'
) x2 ON x1.oc_id::BIGINT = x2.id
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=177.89..14951.55 rows=1 width=8) (actual time=10251.851..10251.851 rows=0 loops=1)
Join Filter: (((x1.data ->> 'trimester_course_id'::text))::bigint = x2.id)
-> Nested Loop (cost=0.00..96.70 rows=1 width=8) (actual time=0.222..5.581 rows=142 loops=1)
Join Filter: (((x2.data ->> 'curriculum_id'::text))::bigint = x3.id)
Rows Removed by Join Filter: 14200
-> Seq Scan on trimester_courses x2 (cost=0.00..65.10 rows=7 width=131) (actual time=0.012..0.678 rows=142 loops=1)
Filter: (((data ->> 'semester_id'::text))::bigint = 53::bigint)
Rows Removed by Filter: 1263
-> Materialize (cost=0.00..31.14 rows=3 width=8) (actual time=0.001..0.007 rows=101 loops=142)
-> Seq Scan on tags x3 (cost=0.00..31.12 rows=3 width=8) (actual time=0.140..0.227 rows=101 loops=1)
Filter: ((data ->> 'type'::text) = 'curriculum'::text)
Rows Removed by Filter: 574
-> Hash Join (cost=177.89..14836.68 rows=908 width=105) (actual time=72.154..72.154 rows=0 loops=142)
Hash Cond: (((student_credits.data ->> 'open_course_id'::text))::bigint = x1.id)
-> Seq Scan on student_credits (cost=0.00..14629.24 rows=910 width=396) (actual time=36.960..72.137 rows=33 loops=142)
Filter: (((data ->> 'student_id'::text))::bigint = 5500::bigint)
Rows Removed by Filter: 181979
-> Hash (cost=128.00..128.00 rows=3991 width=105) (actual time=1.406..1.406 rows=3991 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 549kB
-> Seq Scan on open_courses x1 (cost=0.00..128.00 rows=3991 width=105) (actual time=0.005..0.656 rows=3991 loops=1)
Filter: (NOT is_deleted)
Rows Removed by Filter: 9
Planning time: 0.312 ms
Execution time: 10251.902 ms
(24 rows)
问题是,为什么用视图(3-5)查询JOIN,在这种情况下这么慢?