繁体   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