簡體   English   中英

MySQL - 如何在WHERE x IN中使用索引( <subquery> )

[英]MySQL - how to use index in WHERE x IN (<subquery>)

我正在使用此查詢來獲取名稱以小寫字母“a”開頭的{客戶端}的所有員工:

SELECT * FROM employees 
  WHERE client_id IN (SELECT id FROM clients WHERE name LIKE 'a%')

employees.client_id是一個int,帶有INDEX client_id (index_id) 子查詢應該IMHO返回一個id-s列表,然后在WHERE子句中使用。

當我EXPLAIN查詢時,主查詢使用沒有索引( type:ALL )。 但是,當我EXPLAIN從子查詢取一個列表(例如SELECT ... WHERE client_id IN (121,184,501)EXPLAIN開關type:range ,而這個查詢了50%變快。

如何使查詢使用子查詢返回的數據的索引 - 或者,是否有更有效的方法來檢索此數據? (將id-list檢索到應用程序服務器,加入它並發送第二個查詢在這里更加昂貴)。

提前致謝。

SELECT employees.*
FROM   employees, clients
WHERE  employees.client_id = clients.id
AND    clients.name LIKE 'a%';

應該更快,因為優化者可以選擇最有效的計划。 在使用子查詢編寫它時,您強制它按特定順序執行步驟,而不是讓它選擇最佳連接順序。

作為一般規則,應該避免子查詢,因為它們通常不如連接查詢高性能(盡管在某些情況下它們是不可避免的)

您是否嘗試使用JOIN而非子選擇來執行此操作?

SELECT employees.* FROM employees, clients WHERE employees.client_id = clients.id  AND clients.name LIKE 'a%';

有關原因的具體說明

SELECT * FROM employees WHERE client_id IN (SELECT id FROM clients WHERE name LIKE 'a%')

比...慢

SELECT * FROM employees WHERE client_id IN (1,2,3,4)

查看MySQL手冊的這一部分,特別是第三點: http//dev.mysql.com/doc/refman/5.0/en/subquery-restrictions.html 此外,這個錯誤報告

值得指出的是,對於每個DBMS而言,連接執行優於子查詢並不適用。 但它確實適用於MySQL。

SELECT e.*  
FROM employees e  
WHERE EXISTS (   
  SELECT 1    
  FROM clients c  
  WHERE c.id = e.client_id   
  AND c.name LIKE 'a%'
)

您可以使用EXISTS重寫查詢。 在MySQL中,它肯定會帶來性能提升。 有關更多優化幫助,您可以參考: MySQL-In-Query-Optimization

select * from X as _x where 
  exists(select * from Y as _y where _y.someField = _x.someField)

應該為你做的伎倆;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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