【发布时间】:2019-07-01 16:56:10
【问题描述】:
使用 Rails 和 Postgres。
我有 3 张桌子(我们称它们为“制造商”、“直升机”和“船”)。 制造商模型与 has_many 关联到 Helicopter(通过“manufacturer_helicopters”表和模型)以及与 has_many 关联到 Boats(通过“manufacturer_boats”表和模型)。
在显示页面上,我应该呈现连接到 Helicopter(具有“helicopter_ids”之一)或连接到 Boat(具有“boat_ids”之一)的唯一制造商。
此外,“直升机”关联具有更高的优先级,因此我们应该只过滤那些具有给定直升机 ID 的“直升机”或根本没有“直升机”的制造商。
这是我提出的查询,但它真的很慢 - 查询需要几秒钟(每个表有近 100 万条记录)
result = Manufacturer.distinct(:id)
.left_outer_joins(:manufacturer_helicopters, :manufacturer_boats)
.where('helicopter_id IN (?) OR boat_id IN (?)', helicopter_ids, boat_ids)
result.where('manufacturer_helicopters.helicopter_id = ? OR manufacturer_helicopters.helicopter_id IS NULL', helicopter_id)
我非常感谢任何关于如何提高性能的建议。
编辑 这里解释一下
Unique (cost=104750.30..115799.60 rows=184155 width=384)
-> Sort (cost=104750.30..105210.69 rows=184155 width=384)
Sort Key: manufacturer.id, manufacturer.full_name, manufacturer.serial_number, manufacturer.contact_email, manufacturer.pending, manufacturer.created_at, manufacturer.updated_at, manufacturer.in_production, manufacturer.in_planning, manufacturer.web_url, manufacturer.mobile_url, manufacturer.country, manufacturer.city, manufacturer.zip_code, manufacturer.logo, manufacturer.street, manufacturer.address, manufacturer.last_manufactured_at, manufacturer.archived, manufacturer.external_manufacturer_id, manufacturer.external_serial_number, manufacturer.distributor_id, manufacturer.visible
-> Merge Left Join (cost=1.35..24441.43 rows=184155 width=384)
Merge Cond: (manufacturer.id = manufacturer_helicopter.helicopter_id)
Filter: ((manufacturer_helicopter.helicopter_id = 4) OR (manufacturer_boat.boat_id = 1))
-> Merge Left Join (cost=1.06..19442.76 rows=260211 width=388)
Merge Cond: (manufacturer.id = manufacturer_boat.boat_id)
-> Index Scan using manufacturer_pkey on manufacturers (cost=0.42..11437.12 rows=260211 width=384)
-> Index Scan using manufacturer_on_boat_id_boat on manufacturer_boat (cost=0.42..5352.52 rows=160207 width=8)
-> Index Scan using index_manufacturer_helicopter_on_helicopter_id on manufacturer_helicopter (cost=0.29..3343.37 rows=100005 width=8)
【问题讨论】:
-
我将首先在您的查询上运行
explain以查看瓶颈在哪里。右 btree 索引可能会解决您的问题
标签: sql ruby-on-rails postgresql