哪两个MySQL查询更有效?

时间:2010-10-18 21:04:22

标签: sql mysql performance

SELECT *
  FROM openorders_tracking
  WHERE id NOT IN (SELECT tracking_id FROM openorders_commission)

SELECT *
  FROM openorders_tracking
LEFT JOIN openorders_commission
  ON openorders_tracking.id=openorders_commission.tracking_id
WHERE openorders_commission.id IS NULL

我想知道这个查询,特别是如果存在显着差异。

我还没有任何数据,也没有索引。我想如果“NOT IN”比JOIN更好,反之亦然。

对于那些喜欢EXPLAIN的人来说,这是现在的结果(再次,除了初选之外还没有索引):

mysql> explain SELECT * FROM openorders_tracking WHERE id NOT IN (SELECT trackin
g_id FROM openorders_commission);
+----+--------------------+-----------------------+--------+---------------+----
--+---------+------+------+---------------------+
| id | select_type        | table                 | type   | possible_keys | key
  | key_len | ref  | rows | Extra               |
+----+--------------------+-----------------------+--------+---------------+----
--+---------+------+------+---------------------+
|  1 | PRIMARY            | openorders_tracking   | ALL    | NULL          | NUL
L | NULL    | NULL |  341 | Using where         |
|  2 | DEPENDENT SUBQUERY | openorders_commission | system | NULL          | NUL
L | NULL    | NULL |    0 | const row not found |
+----+--------------------+-----------------------+--------+---------------+----
--+---------+------+------+---------------------+
2 rows in set (0.00 sec)

mysql> explain SELECT * FROM openorders_tracking LEFT JOIN openorders_commission
 ON openorders_tracking.id=openorders_commission.tracking_id WHERE openorders_co
mmission.id IS NULL;
+----+-------------+-----------------------+--------+---------------+------+----
-----+------+------+---------------------+
| id | select_type | table                 | type   | possible_keys | key  | key
_len | ref  | rows | Extra               |
+----+-------------+-----------------------+--------+---------------+------+----
-----+------+------+---------------------+
|  1 | SIMPLE      | openorders_commission | system | PRIMARY       | NULL | NUL
L    | NULL |    0 | const row not found |
|  1 | SIMPLE      | openorders_tracking   | ALL    | NULL          | NULL | NUL
L    | NULL |  341 |                     |
+----+-------------+-----------------------+--------+---------------+------+----
-----+------+------+---------------------+
2 rows in set (0.00 sec)

6 个答案:

答案 0 :(得分:3)

当你面前有两个查询和数据库时,问一个奇怪的事情。尝试运行它们,并使用EXPLAIN查看执行计划。

我的猜测是,MySQL会将它们优化为相同的执行计划,但这可能取决于列类型和索引方案。

答案 1 :(得分:1)

从纯粹的软件开发方法中攻击这个我会说这是不成熟的优化,你应该努力的是可读性。至于哪个查询更具可读性将是您和您的团队的召唤。虽然这不能回答我认为应该回答的问题(不是由我而是像DBA那样更有资格的人),但你应该总是考虑通过优化获得什么。

取自维基百科(Program optimization

何时优化

优化可能会降低可读性并添加仅用于提高性能的代码。这可能使程序或系统复杂化,使其难以维护和调试。因此,优化或性能调整通常在开发阶段结束时执行。

Donald Knuth就优化发表了以下两条声明:

  

“我们应该忘记小事   效率,约占97%   时间:过早优化是   万恶之源“

(几年后他也把这句话归咎于Tony Hoare,虽然这可能是一个错误,因为Hoare声称创造了这个短语。)

  

“在已建立的工程中   纪律改善了12%,很容易   获得,从未被认为是边缘的   我相信同样的观点   应以软件为准   工程“

“过早优化”是一个短语,用于描述程序员让性能考虑因素影响一段代码的设计。这可能导致设计不像以前那样干净或代码不正确,因为优化会使代码变得复杂,并且程序员会因优化而分散注意力。

另一种方法是首先设计来自设计的代码,然后对结果代码进行分析/基准测试,以查看应优化哪些部分。在这个阶段,简单而优雅的设计通常更容易优化,并且分析可能会发现意外的性能问题,这些问题不会过早优化。

在实践中,通常需要在首次设计软件时牢记性能目标,但程序员要平衡设计和优化的目标。

答案 2 :(得分:0)

我被告知要限制每个查询的SELECT数量,所以基于此我会说JOIN是最有效的。

答案 3 :(得分:0)

我会使用热门查询。它更容易理解,恕我直言,它使用“select *”只会选择你所追求的表格中的列。

然而,他们很可能会有相同的执行计划。

答案 4 :(得分:0)

SELECT *
  FROM openorders_tracking
LEFT JOIN openorders_commission
  ON openorders_tracking.id=openorders_commission.tracking_id
WHERE openorders_commission.id IS NULL

上述查询将更有效率。它们可能会产生相同的性能但是一旦您进行了正确的索引,此查询将始终帮助您。因此,尝试索引表并使用最坏情况测试两个查询(尝试插入越来越多的记录,您将看到差异)

答案 5 :(得分:0)

我一直都认为这类查询的NOT EXISTS变体通常更有效,因为它只检查查询表中查询值的第一次出现 - 例如:

SELECT *
  FROM openorders_tracking t
  WHERE NOT EXISTS
  (SELECT NULL FROM openorders_commission c
   WHERE c.tracking_id = t.id)

与以往一样,检查查询的实际效果以确定哪个更快。