我在postgresql中有一堆表,我按如下方式运行查询
SELECT DISTINCT ON ...some stuff...
FROM "rent_flats" INNER JOIN "rent_flats_linked_users"
ON "rent_flats_linked_users"."rent_flat_id" = "rent_flats"."id"
INNER JOIN "users"
ON "users"."id" = rent_flats_linked_users"."user_id"
INNER JOIN "owners"
ON "owners"."id" = "users"."profile_id" AND "users"."profile_type" = 'Owner'
INNER JOIN "phone_numbers"
ON "phone_numbers"."person_id" = "owners"."id" AND "phone_numbers"."person_type" = 'Owner'
INNER JOIN "phone_number_categories"
ON "phone_number_categories"."id" = "phone_numbers"."phone_number_category_id"
INNER JOIN "localities"
ON "localities"."id" = "rent_flats"."locality_id"
INNER JOIN "regions"
ON "regions"."id" = "localities"."region_id"
INNER JOIN "cities"
ON "cities"."id" = "regions"."city_id"
INNER JOIN "property_types"
ON "property_types"."id" = "rent_flats"."property_type_id"
INNER JOIN "apartment_types"
ON "apartment_types"."id" = "rent_flats"."apartment_type_id"
WHERE "rent_flats"."status" = 3
AND (((extract(epoch from age(current_date,rent_flats.date_added))/86400)::int) IN (cities.short_period,cities.long_period))
AND (phone_number_categories.name IN ('SMS','SMS & Mobile'))
ORDER BY rf_id, phone_numbers.priority ASC
注意: rent_flats表包含大约500万行,rent_flats_linked_users包含大约600k行,用户包含350k行。其他表格很小。
查询大约需要6.8秒才能执行,解释分析显示,大约50%的总时间用于连续扫描rent_flats,users和rent_flats_linked_users表,另外30%用于Hash连接。
将seq_scan设置为off ...查询需要更长时间~11秒(在这种情况下,Hash和Hash连接占用时间的97.5%)
Here's the explain query plan analyses. 我已将索引放在内部联接中涉及的字段以及过滤器中涉及的字段上,例如phone_numbers.priority和cities.short_period以及cities.long_period。但我仍然得到顺序扫描。可以解释查询的原因和可能的解决方案是什么?
答案 0 :(得分:1)
我怀疑如果该查询的一部分值得优化,那就是:
(((extract(epoch from age(current_date,rent_flats.date_added))/86400)::int) IN (cities.short_period,cities.long_period))
你真的需要把它变成像:
rent_flats.date_added in (...)
然后你可以索引date_added,也可以索引(date_added,status)。
下一步是确保连接列已编入索引。