如何优化“ IN(SELECT ...)”查询

时间:2019-09-04 10:49:42

标签: mysql optimization

我正在尝试从两个表中进行选择,table_a有6亿行,而table_b只有20行。

当前代码类似于下面的代码。

        SELECT
            field_1,field_2
        FROM
            table_a
        WHERE
             table_a.field_3 IN (SELECT field_3 FROM table_b WHERE field_4 LIKE 'some_phrase%')

它工作正常,但速度很慢。我猜这很慢,因为它必须使用WHERE中的select检查每一行。我以为可以用select中的值创建一个变量,然后使用变量而不是嵌套的select,但是我无法使其正常工作。我在想这样的事情:

SELECT  @myVariable :=field_3 FROM table_b WHERE field_4 LIKE 'some_phrase%;

        SELECT
            field_1,field_2
        FROM
            table_a
        WHERE
             table_a.field_3 IN (@myVariable)

我了解到它不适用于IN(),所以我也尝试了FIND_IN_SET,但我也无法使其正常工作。我将不胜感激。

2 个答案:

答案 0 :(得分:1)

您可以在子查询上使用JOIN代替IN子句

  SELECT field_1,field_2
  FROM  table_a
  INNER JOIN  (
    SELECT field_3 
    FROM table_b 
    WHERE field_4 LIKE 'some_phrase%'
 ) t on t.field_3 =   table_a.field_3 

但是请确保您在field_3的{​​{1}}列上有正确的索引 以及table_b的{​​{1}}列

答案 1 :(得分:0)

实际上,假设table_b上的子查询不是特别大或性能不佳,您可能要集中精力优化table_a上的外部查询。添加适当的索引是一种选择,例如:

CREATE INDEX idx ON table_a (field_3, field_1, field_2);

此索引应完全涵盖WHERESELECT子句。注意,对于子查询,MySQL只会对其进行一次评估,并将结果集缓存在某个地方。如果子查询很大,那么您可能想使用联接重写查询:

SELECT DISTINCT a.field_1, a.field_2
FROM table_a a
INNER JOIN table_b b
    ON a.field_3 = b.field_3
WHERE
    b.field_4 LIKE 'some_phrase%';

以下附加索引可能会有所帮助:

CREATE INDED idx2 ON table_b (field_4, field_3);