如何解决慢速非重复查询

时间:2019-07-01 16:56:10

标签: sql ruby-on-rails postgresql

使用Rails和Postgres。

我有3张桌子(我们称它们为“制造商”,“直升机”和“船”)。 制造商模型与has_many关联到直升机(通过“ manufacturer_helicopters”表和模型),与has_many关联到Boats(通过“ manufacturer_boats”表和模型)。

在显示页面上,我应该呈现与直升机(具有“ helicopter_ids”之一)或与船(具有“ 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)

1 个答案:

答案 0 :(得分:0)

maker.id是否已索引?您的maker_pk是什么?