我一直学会避免像瘟疫一样.但他们对我来说是最自然的事情.当我设计一个查询时,我写的第一件事是一个嵌套的查询.然后我将其转换为连接,有时需要很多时间才能正确.很少提高性能(有时它会)
解决方法
我所知道的因素是:
>如果子查询使用来自外部查询的字段进行比较(否则为correlated)
>如果外部查询和子查询之间的关系被索引覆盖
>如果连接上没有可用的索引,并且子查询不相关,并返回一个小的结果,可能会更快地使用它
>我也遇到了将使用order by的查询转换为不使用它的查询的情况,而不是将其转换为简单的子查询和排序,从而提高了MysqL中的性能
无论如何,测试不同的变体(使用sql_NO_CACHE)总是很好,将相关查询转换为联接是一个很好的做法.
我甚至会说这个非常有用的做法.
可能的是,如果相关的查询是您首先想到的主要思想是设置操作,但主要是在程序操作方面以及处理关系数据库时,完全采用该集合是非常有用的对数据模型和转型的观点.
编辑:
程序与关系
在设置操作与程序性方面的思考归结为某些集合代数表达式中的等价,例如联合上的选择等同于选择的并集.两者没有区别.
但是,当比较两个过程时,例如将选择标准应用于使用联合的联合的每个元素,然后应用选择,这两个过程是明显不同的过程,可能具有非常不同的属性(例如,cpu,I / O,内存).
关系数据库背后的想法是,您不要尝试描述如何获取结果(过程),而只需要您想要的内容,并且数据库管理系统将决定最佳路径(过程)以满足您的请求.这就是为什么sql被称为4th generation language (4GL).
帮助你这样做的一个技巧是提醒自己,元组没有固有的顺序(集合元素无序).
另一个是意识到关系代数是非常全面的,并且允许将请求(要求)直接转换到sql(如果你的模型的语义很好地表达了问题空间,或者换句话说,如果连接到你的表和关系的名称的意思是正确的,或换句话说,如果您的数据库设计良好).
因此,你不必考虑如何,只有什么.
在你的情况下,这只是对相关查询的偏好,所以可能是我没有告诉你任何新的东西,但你强调了这一点,因此这个评论.
我认为,如果您完全满足将查询从一种形式转换为另一种形式(rules(如分配性))的所有规则,您不会喜欢相关的子查询(您将看到所有表单相等).
(注意:上面讨论了理论背景,对于数据库设计很重要;实际上上述概念偏离 – 并不是所有等效的查询重写都必须像快速一样执行,集群主键确实使表在磁盘上具有继承顺序等等,但这些偏差只是偏差;事实上并非所有等效查询执行的速度都是实际DBMS的缺陷,而不是其背后的概念)