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)
答案 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)
与以往一样,检查查询的实际效果以确定哪个更快。