簡體   English   中英

MySQL優化的聯接查詢,條件為“ OR”

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM