我遇到了一些遗留代码,在这些代码中,他们使用了两个内连接,我将其替换为以下内容。
select p.id
from publisher p
inner join retailer r on p.retailer_id = r.id
where p.id IN (1,4,5 .... around 100 or more random ids I get from code)
order by case r.sector_id when r.sector_id then 1 else 2 end,
p.seo_frontpage_factor asc,
case (r.poi_sector_id) when r.poi_sector_id then 3 else 4 end,
p.id asc
以前的查询如下所示。
select p.id
from publisher p
inner join retailer r on p.retailer_id = r.id
inner join (select 1 as id union all select 2 ,union all select 3 ......) as x on p.id = x.id
order by case r.sector_id when r.sector_id then 1 else 2 end,
p.seo_frontpage_factor asc,
case (r.poi_sector_id) when r.poi_sector_id then 3 else 4 end,
p.id asc
我的问题是,这是一个减少内部联接以提高性能的好主意吗?如果不是我可以做什么来优化这个,或者这很好,因为它是?
答案 0 :(得分:1)
IN子句比内连接更具可读性。因此,进行此更改以提高可读性是个好主意。优化器应该将两个查询视为相同,如果它有任何好处: - )
该查询显然是为了对其零售商的100多个发布商ID进行排名。仅返回发布商ID是非常罕见的,但是,我们不知道结果当然是做了什么。显然,应用程序只需要零售商排名的ID。
更新:由于joop,我在下一部分中出现了错误,现在已经纠正了。
您可以进一步提高可读性:
case r.sector_id when r.sector_id then 1 else 2 end
就是
case when r.sector_id is null then 2 else 1 end
相同
case (r.poi_sector_id) when r.poi_sector_id then 3 else 4 end
是
case when r.poi_sector_id is null then 4 else 3 end
一种奇怪的写作方式。甚至可能是一个错误。
CASE
表达式在非空值后排序为空,所以我们也可以使用
order by r.sector_id is null, p.seo_frontpage_factor, r.poi_sector_id is null, p.id
因为PostgreSQL在false
之前排序true
(顺便说一句,与MySQL相同)。