避免嵌套查询是多么重要。
我总是学会像躲避瘟疫一样避开它们。但它们对我来说是最自然的事情。当我设计查询时,我首先编写的是嵌套查询。然后我将其转换为联接,这有时需要花费很多时间才能正确。并且很少会带来很大的性能提升(有时确实如此)
那么他们真的那么糟糕吗?有没有办法在没有临时表和文件排序的情况下使用嵌套查询
这确实取决于,我曾经遇到过通过使用子查询改进一些查询的情况。
我所知道的因素是:
- 子查询是否使用外部查询中的字段进行比较(相关的 http://dev.mysql.com/doc/refman/5.1/en/correlated-subqueries.html or not)
- 外查询和子查询之间的关系是否被索引覆盖
- 如果连接上没有可用的索引,并且子查询不相关并返回一个小结果,那么使用它可能会更快
- 我还遇到过这样的情况:将使用 order by 的查询转换为不使用 order by 的查询,然后将其转换为简单的子查询和排序,以提高 mysql 的性能
不管怎样,测试不同的变体总是好的(请使用 SQL_NO_CACHE),并且将相关查询转换为联接是一个很好的实践。
我什至认为这是一种非常有用的做法。
如果相关查询是您首先想到的,那么您可能主要考虑的不是集合操作,而是过程操作,并且在处理关系数据库时,完全采用集合是非常有用的对数据模型及其转换的看法。
EDIT:
过程性与关系性
从集合运算与过程的角度思考可以归结为某些集合代数表达式中的等效性,例如并集上的选择相当于选择的并集。两者没有区别。
但是,当您比较这两个过程时,例如使用 make a union 将选择标准应用于联合的每个元素,然后应用选择,这两个过程是明显不同的过程,它们可能具有非常不同的属性(例如 CPU 的利用率,我/O,记忆)。
关系数据库背后的想法是,您不必尝试描述如何获得结果(过程),而只描述您想要的结果,并且数据库管理系统将决定满足您的请求的最佳路径(过程)。这就是为什么 SQL 被称为第四代语言(4GL) http://en.wikipedia.org/wiki/4GL.
帮助您做到这一点的技巧之一是提醒自己元组没有固有的顺序(集合元素是无序的)。
另一个是认识到关系代数非常全面,并且允许将请求(要求)直接转换为 SQL(如果模型的语义很好地代表了问题空间,或者换句话说,如果附加到表和关系名称的含义正确) ,或者换句话说,如果您的数据库设计得好)。
因此,你不必考虑如何,只需考虑什么。
就您而言,这只是对相关查询的偏好,因此我可能没有告诉您任何新内容,但您强调了这一点,因此发表了评论。
我认为,如果您完全熟悉将查询从一种形式转换为另一种形式的所有规则(rules http://en.wikipedia.org/wiki/Relational_algebra#Selection_.28.CF.83.29例如分配性)您不喜欢相关子查询(您会认为所有形式都是平等的)。
(注意:上面讨论了理论背景,对于数据库设计很重要;实际上,上述概念有所偏差 - 并非所有等效的查询重写都一定会快速执行,聚集主键确实使表在磁盘上继承了顺序,等等......但是这些偏差只是偏差;并非所有等效查询都执行得那么快,这一事实是实际 DBMS 的缺陷,而不是其背后的概念的缺陷)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)