哪个选择语句更好?

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 |桌子|类型可能的钥匙|关键key_len |参考|行|额外|
+ ---- + -------------- + -------- + ------- + ------------- -+ ---------------- + --------- + ------ + ------ + ------- ------------------------- +
| 1 |简单bTable |范围| bTable_yField | bTable_yField | 5 | NULL | 2 |在哪里使用
| 1 |简单表格|全部| NULL | NULL | NULL | NULL | 4 |在哪里使用使用连接缓冲区
+ ---- + -------------- + -------- + ------- + ------------- -+ ---------------- + --------- + ------ + ------ + ------- ------------------------- +

但是,由于优化程序可能会做出不同的决策,因此您实际上必须使用架构和代表性的实际数据进行分析。

通过this excellent articlequassnoi中更多地比较了这些技术。



作为参考,这是我创建aTablebTable(因为您未提供定义)并测试查询的方式:

mysql> CREATE TABLE aTable(aField INT,aMore VARCHAR(200));
查询正常,受影响的0行(0.01秒)

mysql>创建表bTable(xField INT,yField INT);
查询正常,受影响的0行(0.02秒)

mysql>插入aTable(aField,aMore)值(1,'一个'),(2,'两个'),(3,'三个'),(4,'四个');
查询正常,受影响的4行(0.00秒)
记录:4重复:0警告:0

mysql> INSERT INTO bTable(xField,yField)值(1、10),(2、2),(3、20),(4、4);
查询正常,受影响的4行(0.02秒)
记录:4重复:0警告:0

mysql> CREATE INDEX bTable_yField ON bTable(yField);
查询正常,受影响的0行(0.05秒)
记录:0重复项:0警告:0

mysql> SELECT * FROM aTable WHERE aField in(SELECT xField FROM bTable WHERE yField> 5);
+ -------- + ------- +
| aField |更多|
+ -------- + ------- +
| 1 |一|
| 3 |三|
+ -------- + ------- +
设置2行(0.00秒)

mysql> SELECT * FROM aTable WHERE(SELECT yField from bTable WHERE aTable.aField = bTable.xField)> 5;
+ -------- + ------- +
| aField |更多|
+ -------- + ------- +
| 1 |一|
| 3 |三|
+ -------- + ------- +
设置2行(0.00秒)

关于mysql - 更快地执行“WHERE IN(SELECT)”或“WHERE x =(SELECT)”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13050351/

10-11 00:17