OS X上的Postgres 10.3
为什么在#1和#3中会扫描“事件”中的所有行?
为什么将DISTINCT添加到#2(下面的视图#4查询)会导致截然不同的(快速)执行和执行计划?
我对Postgres有非常肤浅的知识(一般来说可以使用DB理论),所以不知道这些怪癖,索引是下一级别。
最初,我正在使用Node + Sequelize执行连接#3,该连接速度很慢,因此尝试了IN。如果“ collection_item”的计数为1,则快速执行。
如果可以避免,我宁愿使用Sequelize生成的查询,而不是手工制作的。
感谢您的帮助。
select "event".* from "event"
where id in (
select item_id
from collection_item
where "collection_item"."collection_id" = 2 and collection_item.item_type = 'event'
)
分析:
Merge Semi Join (cost=2.08..12.60 rows=4 width=1870) (actual time=0.079..6294.739 rows=7 loops=1) |
Merge Cond: (event.id = collection_item.item_id) |
-> Index Scan using idx_event_id on event (cost=0.43..1066819.90 rows=10000215 width=1870) (actual time=0.012..5525.787 rows=9109726 loops=1) |
-> Sort (cost=1.62..1.64 rows=4 width=4) (actual time=0.028..0.029 rows=7 loops=1) |
Sort Key: collection_item.item_id |
Sort Method: quicksort Memory: 25kB |
-> Seq Scan on collection_item (cost=0.00..1.58 rows=4 width=4) (actual time=0.018..0.022 rows=7 loops=1) |
Filter: ((collection_id = 2) AND ((item_type)::text = 'event'::text)) |
Rows Removed by Filter: 33 |
Planning time: 0.412 ms |
Execution time: 6296.260 ms |
select "event".* from "event"
where id = any(
(
select array(
select item_id
from collection_item
where "collection_item"."collection_id" = 2 and collection_item.item_type = 'event'
)
)::integer[]
)
分析
Index Scan using idx_event_id on event (cost=2.03..76.86 rows=10 width=1870) (actual time=0.092..0.119 rows=7 loops=1) |
Index Cond: (id = ANY ($1)) |
InitPlan 2 (returns $1) |
-> Result (cost=1.58..1.59 rows=1 width=32) (actual time=0.043..0.043 rows=1 loops=1) |
InitPlan 1 (returns $0) |
-> Seq Scan on collection_item (cost=0.00..1.58 rows=4 width=4) (actual time=0.035..0.039 rows=7 loops=1) |
Filter: ((collection_id = 2) AND ((item_type)::text = 'event'::text)) |
Rows Removed by Filter: 33 |
Planning time: 0.204 ms |
Execution time: 0.147 ms |
explain analyse SELECT "event"."id", "event"."parent_event_id", "event"."name", "event"."longlink", "event"."summary", "event"."description", "event"."organiser_id", "event"."creator_id", "event"."location_type", "event"."primary_location_id", "event"."primary_event_date_id", "event"."page_template_id", "event"."data", "event"."image", "event"."status", "event"."type", "event"."count_interested", "event"."count_attending", "event"."count_likes", "event"."count_collections", "event"."count_comments", "event"."count_views", "event"."pricing_id", "event"."event_series_id", "event"."owner_type", "event"."owner_id", "event"."publish_at", "event"."calendar_visibility", "event"."max_attendees", "event"."min_attendees", "event"."registration_cost", "event"."registration_visibility", "event"."interest_visibility", "event"."itinerary_id", "event"."ext_id", "event"."ext_application", "event"."lowest_price", "event"."highest_price", "event"."registrations_close_at", "event"."registrations_open_at", "event"."registrations_closed", "event"."tags", "event"."exclude_from_related", "event"."rewards_label", "event"."createdAt", "event"."updatedAt", "collectionItem"."id" AS "collectionItem.id", "primaryLocation"."id" AS "primaryLocation.id", "primaryLocation"."name" AS "primaryLocation.name", "primaryLocation"."description" AS "primaryLocation.description", "primaryLocation"."lat" AS "primaryLocation.lat", "primaryLocation"."lng" AS "primaryLocation.lng", "primaryLocation"."formatted_address" AS "primaryLocation.formatted_address", "primaryLocation"."status" AS "primaryLocation.status", "primaryLocation"."address_1" AS "primaryLocation.address_1", "primaryLocation"."address_2" AS "primaryLocation.address_2", "primaryLocation"."address_3" AS "primaryLocation.address_3", "primaryLocation"."building" AS "primaryLocation.building", "primaryLocation"."city" AS "primaryLocation.city", "primaryLocation"."region" AS "primaryLocation.region", "primaryLocation"."country" AS "primaryLocation.country", "primaryLocation"."post_code" AS "primaryLocation.post_code", "primaryLocation"."owner_type" AS "primaryLocation.owner_type", "primaryLocation"."owner_id" AS "primaryLocation.owner_id", "primaryLocation"."instructions" AS "primaryLocation.instructions", "primaryLocation"."event_count" AS "primaryLocation.event_count", "primaryLocation"."parking_instructions" AS "primaryLocation.parking_instructions", "primaryLocation"."visibility" AS "primaryLocation.visibility", "primaryLocation"."createdAt" AS "primaryLocation.createdAt", "primaryLocation"."updatedAt" AS "primaryLocation.updatedAt", "primaryEventDate"."id" AS "primaryEventDate.id", "primaryEventDate"."event_id" AS "primaryEventDate.event_id", "primaryEventDate"."start_date" AS "primaryEventDate.start_date", "primaryEventDate"."start_time" AS "primaryEventDate.start_time", "primaryEventDate"."start_datetime" AS "primaryEventDate.start_datetime", "primaryEventDate"."end_date"AS "primaryEventDate.end_date", "primaryEventDate"."end_time" AS "primaryEventDate.end_time", "primaryEventDate"."end_datetime" AS "primaryEventDate.end_datetime", "primaryEventDate"."name" AS "primaryEventDate.name", "primaryEventDate"."status" AS "primaryEventDate.status", "primaryEventDate"."details" AS "primaryEventDate.details", "primaryEventDate"."visible_from" AS "primaryEventDate.visible_from", "primaryEventDate"."visible_to" AS "primaryEventDate.visible_to", "primaryEventDate"."type" AS "primaryEventDate.type", "primaryEventDate"."search_visibility" AS "primaryEventDate.search_visibility", "primaryEventDate"."calendar_visibility" AS "primaryEventDate.calendar_visibility", "primaryEventDate"."tz" AS "primaryEventDate.tz", "primaryEventDate"."createdAt" AS "primaryEventDate.createdAt", "primaryEventDate"."updatedAt" AS "primaryEventDate.updatedAt", "userEventTrack"."collection_count" AS "userEventTrack.collection_count", "userEventTrack"."liked" AS "userEventTrack.liked"
FROM "event" AS "event"
INNER JOIN "collection_item" AS "collectionItem" ON "event"."id" = "collectionItem"."item_id" AND "collectionItem"."item_type" = 'event' AND "collectionItem"."collection_id" =2
LEFT OUTER JOIN "location" AS "primaryLocation" ON "event"."primary_location_id" = "primaryLocation"."id"
LEFT OUTER JOIN "event_date" AS "primaryEventDate" ON "event"."primary_event_date_id" = "primaryEventDate"."id"
LEFT OUTER JOIN "user_event_track" AS "userEventTrack" ON "event"."id" = "userEventTrack"."event_id" AND "userEventTrack"."user_id" = 1 LIMIT 20;
分析:
Limit (cost=2.90..16.42 rows=4 width=3676) (actual time=0.100..6207.552 rows=7 loops=1) |
-> Nested Loop Left Join (cost=2.90..16.42 rows=4 width=3676) (actual time=0.100..6207.550 rows=7 loops=1) |
-> Nested Loop Left Join (cost=2.76..15.74 rows=4 width=3664) (actual time=0.094..6207.502 rows=7 loops=1) |
-> Nested Loop Left Join (cost=2.22..13.24 rows=4 width=3359) (actual time=0.092..6207.492 rows=7 loops=1) |
-> Merge Join (cost=2.08..12.60 rows=4 width=1836) (actual time=0.089..6207.012 rows=7 loops=1) |
Merge Cond: (event.id = "collectionItem".item_id) |
-> Index Scan using idx_event_id on event (cost=0.43..1066819.90 rows=10000215 width=1832) (actual time=0.018..5455.081 rows=9109726 loops=1) |
-> Sort (cost=1.62..1.64 rows=4 width=8) (actual time=0.027..0.028 rows=7 loops=1) |
Sort Key: "collectionItem".item_id |
Sort Method: quicksort Memory: 25kB |
-> Seq Scan on collection_item "collectionItem" (cost=0.00..1.58 rows=4 width=8) (actual time=0.014..0.019 rows=7 loops=1) |
Filter: (((item_type)::text = 'event'::text) AND (collection_id = 2)) |
Rows Removed by Filter: 33 |
-> Index Scan using location_pkey on location "primaryLocation" (cost=0.14..0.16 rows=1 width=1523) (actual time=0.067..0.067 rows=0 loops=7) |
Index Cond: (event.primary_location_id = id) |
-> Index Scan using event_date_pkey on event_date "primaryEventDate" (cost=0.55..0.63 rows=1 width=305) (actual time=0.000..0.000 rows=0 loops=7) |
Index Cond: (event.primary_event_date_id = id) |
-> Index Scan using idx_usereventtrack_event on user_event_track "userEventTrack" (cost=0.14..0.16 rows=1 width=16) (actual time=0.005..0.006 rows=1 loops=7) |
Index Cond: (event.id = event_id) |
Filter: (user_id = 1) |
Planning time: 6.875 ms |
Execution time: 6208.728 ms |
select "event".* from "event"
where id in (
select DISTINCT item_id
from collection_item
where "collection_item"."collection_id" = 2 and collection_item.item_type = 'event'
)
分析
Nested Loop (cost=2.03..27.01 rows=3 width=1870) (actual time=0.088..0.143 rows=7 loops=1)
-> HashAggregate (cost=1.59..1.62 rows=3 width=4) (actual time=0.054..0.056 rows=7 loops=1)
Group Key: collection_item.item_id
-> Seq Scan on collection_item (cost=0.00..1.58 rows=4 width=4) (actual time=0.042..0.047 rows=7 loops=1)
Filter: ((collection_id = 2) AND ((item_type)::text = 'event'::text))
Rows Removed by Filter: 33
-> Index Scan using idx_event_id on event (cost=0.43..8.45 rows=1 width=1870) (actual time=0.012..0.012 rows=1 loops=7)
Index Cond: (id = collection_item.item_id)
Planning time: 0.388 ms
Execution time: 0.220 ms