[英]MySQL optimized join query with “OR” condition
我有一個包含50萬個公司資料+他們提供服務的位置的數據庫。所以我有公司表+位置表。 公司可以在全國范圍內或僅在一個城市中提供服務。 位置表如下所示:
ID | company_id | scope | country_id | city_id
1 | 'companyuuid...' | 'city' | 'UK' | '32321'
2 | 'companyuuid...' | 'country' | 'US' | NULL
當公司在全國范圍內提供服務時,我們將范圍“國家”指定為“國家”,而當公司僅在特定城市內提供服務時,則將范圍為“城市”。
不幸的是,當MySQL具有“ OR”語句並考慮數量(如果我們需要使用的數據)時,MySQL處理查詢的速度將非常緩慢。
select distinct companies.id from companies
inner join locations on companies.id = locations.company_id
and (locations.scope = 'city' and locations.city_id = '703448' )
order by companies.score desc limit 12 offset 0
我當前的問題是,在城市內尋找公司時,我還需要展示在全國范圍內提供服務的公司。 顯而易見的方法是添加OR語句,如下所示:
select distinct companies.id from companies
inner join locations on companies.id = locations.company_id
and (locations.scope = 'city' and locations.city_id = '703448' )
or (locations.scope = 'country' and locations.country_id = 'UK' )
order by companies.score desc limit 12 offset 0
但是問題是OR語句會使查詢變得非常慢。 也許還有其他使用附加聯接的方法,這樣我們可以使查詢保持快速嗎?
我建議使用exists
:
select c.id
from companies c
where exists (select 1
from locations l
where l.company_id = c.id and
l.scope = 'city' and
l.city_id = 703448 -- I'm guessing city_id is a number, so no quotes
) or
exists (select 1
from locations l
where l.company_id = c.id and l.scope = 'country'
)
order by c.score desc
limit 12 offset 0;
exists
子查詢可以利用locations(company_id, scope, city_id)
的索引。 該查詢甚至可以利用companies(score)
上的索引。
問題1: OR
似乎是“錯誤的”。 您要英國的所有城市,再加上倫敦的所有城市,包括加拿大的所有城市嗎?
您可能需要AND
而不是OR
。 您將需要“自我加入”才能兩次到達locations
?? EAV模式糟透了。
問題2: x AND y OR z
是(x AND y) OR z
,而不是x AND (y OR z)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.