哪种选择语句更好?
SELECT *
FROM aTable
WHERE aField in (
SELECT xField
FROM bTable
WHERE yField > 5
);
或
SELECT *
FROM aTable
WHERE (
SELECT yField
FROM bTable
WHERE aTable.aField = bTable.xField
) > 5;
最佳答案
它们生成非常相似的执行计划(在我的测试表上,它们很小;YMMV,始终分析真实数据),您可能需要考虑第三种替代方案:
第一个:
EXPLAIN SELECT * FROM aTable WHERE aField in (SELECT xField FROM bTable WHERE yField > 5);
+----+--------------------+--------+-------+---------------+---------------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+--------+-------+---------------+---------------+---------+------+------+-------------+ | 1 | PRIMARY | aTable | ALL | NULL | NULL | NULL | NULL | 4 | Using where | | 2 | DEPENDENT SUBQUERY | bTable | range | bTable_yField | bTable_yField | 5 | NULL | 2 | Using where | +----+--------------------+--------+-------+---------------+---------------+---------+------+------+-------------+
The second:
EXPLAIN SELECT * FROM aTable WHERE (SELECT yField FROM bTable WHERE aTable.aField = bTable.xField) > 5;
+----+--------------------+--------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+--------+------+---------------+------+---------+------+------+-------------+ | 1 | PRIMARY | aTable | ALL | NULL | NULL | NULL | NULL | 4 | Using where | | 2 | DEPENDENT SUBQUERY | bTable | ALL | NULL | NULL | NULL | NULL | 4 | Using where | +----+--------------------+--------+------+---------------+------+---------+------+------+-------------+
Both result in a dependent subquery; on my example tables, the first one gets the benefit of the index (I assume bTable.yField
is indexed) while the second doesn't.
You can avoid the dependent subquery and get better up-front filtering using a JOIN
:
The third alternative:
EXPLAIN SELECT * FROM aTable INNER JOIN bTable On aTable.aField = bTable.xField WHERE bTable.yField > 5;
+----+-------------+--------+-------+---------------+---------------+---------+------+------+--------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+-------+---------------+---------------+---------+------+------+--------------------------------+ | 1 | SIMPLE | bTable | range | bTable_yField | bTable_yField | 5 | NULL | 2 | Using where | | 1 | SIMPLE | aTable | ALL | NULL | NULL | NULL | NULL | 4 | Using where; Using join buffer | +----+-------------+--------+-------+---------------+---------------+---------+------+------+--------------------------------+
同样,您确实必须使用您的 架构和您的 具有代表性的真实世界数据进行分析,因为优化器可能会做出不同的决定。
在 this excellent article 中对这些技术进行了更多比较通过 quassnoi .
作为引用,下面是我如何创建 aTable
和 bTable
(因为您没有提供定义)并测试您的查询:
mysql> CREATE TABLE aTable (aField INT, aMore VARCHAR(200)); Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE bTable (xField INT, yField INT); Query OK, 0 rows affected (0.02 sec) mysql> INSERT INTO aTable (aField, aMore) VALUES (1, 'One'), (2, 'Two'), (3, 'Three'), (4, 'Four'); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> INSERT INTO bTable (xField, yField) VALUES (1, 10), (2, 2), (3, 20), (4, 4); Query OK, 4 rows affected (0.02 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> CREATE INDEX bTable_yField ON bTable(yField); Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM aTable WHERE aField in (SELECT xField FROM bTable WHERE yField > 5); +--------+-------+ | aField | aMore | +--------+-------+ | 1 | One | | 3 | Three | +--------+-------+ 2 rows in set (0.00 sec) mysql> SELECT * FROM aTable WHERE (SELECT yField FROM bTable WHERE aTable.aField = bTable.xField) > 5; +--------+-------+ | aField | aMore | +--------+-------+ | 1 | One | | 3 | Three | +--------+-------+ 2 rows in set (0.00 sec)
关于mysql - 更快地执行 'WHERE IN (SELECT)' 或 'WHERE x = (SELECT)',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13050351/