2017-09-05 20 views
1

從表中,我試圖讓加快(重寫?)不是一個子選擇查詢

一)誰履行其在鍵/值組合在一個表中持有一定標準的用戶

沒有誰在所有

這樣的鍵/值組合,例如,試圖找到誰住在法國或誰沒有被添加到他們的位置,我的用戶

OR

b)用戶使用這個(簡體)查詢:

SELECT * 
FROM 
    current_users 
    JOIN current_users um_location ON current_users.id = um_location.id 
WHERE 
    (
     (um_location.meta_key = 'location' AND um_location.meta_value = 'France') 
    OR 
     (current_users.id NOT IN 
      (SELECT current_users.id FROM current_users WHERE current_users.meta_key = 'location') 
     ) 
    ) 

問題是,當然,運行OR子選擇查詢(如果這就是所謂的)會極大地減慢查詢速度。而且由於完整的查詢有大約5或6個這樣的子選擇,所以它放慢了太多的速度。

有沒有另一種方式做到這一點?更快的方式?

回答

0

更改或病症UNION查詢的替代或

SELECT * FROM 
    current_users 
    JOIN current_users um_location ON current_users.id = um_location.id 
WHERE 
    um_location.meta_key = 'location' AND um_location.meta_value = 'France' 
UNION 
SELECT * FROM 
    current_users 
    JOIN current_users um_location ON current_users.id = um_location.id 
WHERE 
    current_users.id NOT IN 
    (SELECT current_users.id FROM current_users WHERE 
    current_users.meta_key='location') 
0

這應該是最簡潔的可能:

SELECT * 
FROM current_users 
LEFT JOIN current_users AS um_location 
    ON current_users.id = um_location.id 
    AND um_location.meta_key = 'location' 
WHERE um_location.meta_value = 'France' 
    OR um_location.meta_value IS NULL 
; 

...但isaace答案提示,MySQL不處理OR條件理想。 所以,這可能會表現更好。

SELECT * 
FROM current_users 
LEFT JOIN current_users AS um_location 
    ON current_users.id = um_location.id 
    AND um_location.meta_key = 'location' 
WHERE um_location.meta_value = 'France' 
UNION 
SELECT * 
FROM current_users 
LEFT JOIN current_users AS um_location 
    ON current_users.id = um_location.id 
    AND um_location.meta_key = 'location' 
WHERE um_location.meta_value IS NULL 
; 

..但它可能只會有所不同,如果你有meta_value索引;因爲問題在於MySQL在向OR提交時傾向於忽略索引。


編輯:由於架構設計的種類開始使用,則可能是這些查詢使用「location」條目上的加盟左側行一些奇怪的問題;試試這個。

SELECT * 
FROM current_users AS non_location 
LEFT JOIN current_users AS um_location 
    ON current_users.id = um_location.id 
    AND um_location.meta_key = 'location' 
WHERE non_location.meta_key != 'location' 
    AND (um_location.meta_value = 'France' 
     OR um_location.meta_value IS NULL 
     ) 
; 
0

首先,謝謝你的建議。不幸的是我不能讓他們的工作作爲連接

LEFT JOIN current_users AS um_location 
ON current_users.id = um_location.id 
AND um_location.meta_key = 'location' 

沒有回誰還沒有進入他們的位置的用戶的記錄。

但是,經過很多工作,我設法解決了這個問題。這不是優雅,但它的工作原理:

  1. 創建一個臨時表與滿足一些基本條件的用戶的子集。
  2. 做一個簡單的INSERT IGNORE INTO ... SELECT DISTINCT ... FROM current_users在虛擬信息中添加缺少的「位置」。

然後最終查詢這個包括:

um_location.meta_value = 'France' 
or 
um_location.meta_value = 'dummyinfo' 

這不是極快,但因爲這是作用在與後端admin用戶的一個過程只有他們等得起......;)

再次感謝您的幫助!

+0

我想我找到了問題,看我的編輯。 – Uueerdo