gpt4 book ai didi

mysql - 更快地执行 'WHERE IN (SELECT)' 或 'WHERE x = (SELECT)'

转载 作者:太空宇宙 更新时间:2023-11-03 11:04:25 25 4
gpt4 key购买 nike

哪种选择语句更好?

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 .


作为引用,下面是我如何创建 aTablebTable(因为您没有提供定义)并测试您的查询:

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: 0mysql> 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: 0mysql> CREATE INDEX bTable_yField ON bTable(yField);Query OK, 0 rows affected (0.05 sec)Records: 0  Duplicates: 0  Warnings: 0mysql> 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com