MySQL是否足够聪明,可以优化未使用的连接中的引用完整性?

xqkwcwgp  于 2023-04-10  发布在  Mysql
关注(0)|答案(1)|浏览(119)

下面是两个等价的查询(因为外键约束+主键):

CREATE TABLE customers ( id int PRIMARY KEY );
CREATE TABLE orders ( id int, customer_id int );
ALTER TABLE orders ADD FOREIGN KEY (customer_id) REFERENCES customers(id);

SELECT id
     , (SELECT 1 FROM customers c WHERE c.id = o.id) one
  FROM orders o;

SELECT o.id
     , 1 one
  FROM orders o
  JOIN customers c
    ON c.id = o.customer_id;

在这两种情况下,orders的每一行都将在结果中有一行。
这也意味着,如果所有这些查询(其中一个)都是某个其他查询的子查询,并且该其他查询不使用one列,则可以跳过连接。

我的问题是:MySQL是否足够聪明,可以在这两种情况下跳过连接?如果我切换到NULL列和LEFT JOIN列,会怎么样?

我现在正在制作一些视图来对一些报表进行非规范化。所以我需要了解是否有一些规范的格式(bikeshedding?)我应该用于这样的事情,以确保我的巨大视图能够有效地进行最低限度的处理。

eimct9ow

eimct9ow1#

它绝对能够优化子查询、CTE和VIEW中未使用的列和查找。
它具体做什么取决于版本和确切的DDL、查询和索引统计信息。在MariaDB上,ANALYZE FORMAT=JSON SELECT ...将显示实际的执行计划。在Oracle MySQL上,使用EXPLAIN ANALYZE SELECT ...
需要记住的是,查询计划会随着表的增长而变化(随着统计数据变得陈旧,请偶尔执行ANALYZE TABLE)。
如果你的应用变得很大,你可能想禁用外键检查,并使用好的代码来强制完整性。强制的FK占用CPU时间和IO。所以,在其他条件相同的情况下,不要依赖像FK这样的约束。尽可能编写不需要它们的代码。(但是,当然,如果你的代码在启用FK约束时更有意义,那就继续这样写吧。)
设计您的查询、CTE、VIEW等,使其易于阅读和推理。让您的应用正常工作。然后,如果您有幸拥有一个不断增长的应用程序,其中的表不断增长,请每三个月左右重新审视瓶颈查询计划。
我设计了表、索引和约束,将它们投入生产,然后不得不向我的继任者解释它们。然而,我从来没有,甚至一次,在我移交工作时,“哇,我应该让这个数据库更复杂或更聪明”。很多时候我想“我希望以前的自己能设计得更简单”。
有一个口号说“过早的优化是万恶之源”。这是一个夸张的说法。但公平地说,过早的数据库优化

相关问题