[英]How to optimize the “IN (SELECT…” query
我正在尝试从两个表中进行选择,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
但也无法使其工作。 我将不胜感激任何帮助。
代替IN子句,您可以在子查询上使用JOIN
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
的table_b
列和field_3
的table_a
列上有正确的索引
实际上,假设table_b
上的子查询不是特别大或性能不佳,则您可能需要集中精力优化table_a
上的外部查询。 添加适当的索引是一种选择,例如:
CREATE INDEX idx ON table_a (field_3, field_1, field_2);
该索引应完全覆盖WHERE
和SELECT
子句。 注意,对于子查询,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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.