代码之家  ›  专栏  ›  技术社区  ›  Piskvor left the building Rohit Kumar

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

  •  8
  • Piskvor left the building Rohit Kumar  · 技术社区  · 16 年前

    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-s列表,然后在WHERE子句中使用该列表。

    当我 EXPLAIN type:ALL SELECT ... WHERE client_id IN (121,184,501) ),即 切换到 type:range ,此查询速度将加快50%。

    如何使查询使用子查询返回的数据的索引?或者,是否有更有效的方法检索此数据?(在这里,将id列表检索到ApplicationServer、加入它并发送第二个查询的成本更高)。

    6 回复  |  直到 14 年前
        1
  •  12
  •   Asciiom    12 年前
    SELECT employees.*
    FROM   employees, clients
    WHERE  employees.client_id = clients.id
    AND    clients.name LIKE 'a%';
    

    应该更快,因为乐观主义者可以选择最有效的计划。以子查询的方式编写时,您强制它按特定顺序执行步骤,而不是让它选择最佳连接顺序。

    通常应避免子查询,因为它们的性能通常不如连接查询(尽管在某些情况下它们是不可避免的)

        2
  •  5
  •   mat    16 年前

    JOIN

    SELECT employees.* FROM employees, clients WHERE employees.client_id = clients.id  AND clients.name LIKE 'a%';
    
        3
  •  4
  •   James Healy    15 年前

    关于原因的具体解释

    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)
    

    http://dev.mysql.com/doc/refman/5.0/en/subquery-restrictions.html . 还有这个 bug report .

        4
  •  2
  •   nem nem    16 年前

    值得指出的是,连接的性能优于子查询,这并不适用于所有DBMS。但对于MySQL来说确实如此。

        5
  •  1
  •   Rishi Agarwal    16 年前
    SELECT e.*  
    FROM employees e  
    WHERE EXISTS (   
      SELECT 1    
      FROM clients c  
      WHERE c.id = e.client_id   
      AND c.name LIKE 'a%'
    )
    

    您可以使用 . 在MySQL中,它无疑提高了性能。有关更多优化帮助,您可以参考: MySQL-In-Query-Optimization

        6
  •  0
  •   Thomas Hansen    16 年前
    select * from X as _x where 
      exists(select * from Y as _y where _y.someField = _x.someField)