8

このクエリを使用して、{小文字の「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)。サブクエリは、IDのリストをIMHOが返す必要があります。これは、WHERE句で使用されます。

クエリをEXPLAIN実行すると、プライマリクエリはインデックスを使用しません(type:ALL)。しかし、サブクエリ(たとえば)EXPLAIN から取得したリストを実行すると、に切り替わり、このクエリは50%高速になります。SELECT ... WHERE client_id IN (121,184,501)EXPLAINtype:range

サブクエリによって返されるデータのインデックスをクエリに使用させるにはどうすればよいですか?または、このデータを取得するためのより効率的な方法はありますか?(IDリストをアプリケーションサーバーに取得し、それに参加して2番目のクエリを送信すると、ここではさらにコストがかかります)。

前もって感謝します。

4

6 に答える 6

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

オプティマイザーは最も効率的なプランを選択できるため、より迅速に実行する必要があります。サブクエリを使用して作成する場合、最適な結合順序を選択させるのではなく、特定の順序でステップを実行するように強制します。

原則として、サブクエリは通常、結合クエリよりもパフォーマンスが低いため、避ける必要があります(ただし、避けられない場合もあります)。

于 2008-12-04T09:32:48.537 に答える
5

サブセレクションではなく、でこれを実行しようとしましたJOINか?

SELECT employees.* FROM employees, clients WHERE employees.client_id = clients.id  AND clients.name LIKE 'a%';
于 2008-12-04T09:33:14.980 に答える
4

理由の具体的な説明については

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 マニュアルのこの部分、特に 3 番目のドット ポイントを確認してください: http://dev.mysql.com/doc/refman/5.0/en/subquery-restrictions.html。また、このバグレポート.

于 2009-07-22T02:54:58.713 に答える
2

結合がサブクエリよりも優れたパフォーマンスを発揮するということは、存在するすべての DBMS に当てはまるわけではないことに注意してください。ただし、MySQLの場合は確かにそうです。

于 2008-12-04T12:12:07.687 に答える
1
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を参照してください。

于 2008-12-04T13:23:53.533 に答える
0
select * from X as _x where 
  exists(select * from Y as _y where _y.someField = _x.someField)

あなたのためにトリックをするべきです;)

于 2008-12-04T12:17:16.617 に答える