回答

收藏

避免嵌套查询

技术问答 技术问答 255 人阅读 | 0 人回复 | 2023-09-14

避免嵌套查询有多重要。% x. U, u" E- x; D
我一直学会避免像瘟疫一样躲避它们。但是对我来说,它们是最自然的事情。在设计查询时,我首先写的是嵌套查询。然后,我将其转换为联接,有时需要花费很多时间才能正确。而且很少会带来很大的性能提升(有时确实会提高)
0 R3 R$ s9 L0 D; |4 g: {% z8 f他们真的那么糟糕吗?有没有一种方法可以使用没有临时表和文件排序的嵌套查询
' o4 g/ P& z) v9 U9 F                , I/ w+ }7 G0 c1 i
解决方案:
" v0 ^+ Z( v- C5 o$ W6 y# h                & m4 o" U1 g7 P) x% i  ^

) ?2 p7 K0 N$ R+ `7 B# P  @& V# e6 ?! s8 p4 f* ]. }
                这确实取决于我遇到的情况,我可以通过使用子查询来改进一些查询。
  j7 p3 u1 y3 o  v% I7 @我知道的因素有:. [( g" M! C; H: J
子查询是否使用外部查询中的字段进行比较(是否相关)
. B4 T" Q+ _2 Y& a6 b' \如果外部查询和子查询之间的关系被索引覆盖
  S9 g, n" v1 D8 `如果联接上没有可用的索引,并且子查询没有关联并返回较小的结果,则使用它可能会更快! b8 _3 u0 W) b4 t3 k
我也遇到过这样的情况,其中将使用order by的查询转换为不使用它的查询,而不是将其转换为简单的子查询并进行排序,从而提高了mysql的性能。
- p$ {" i+ w/ R8 w  g

2 Y' q0 k- u& H6 a) W) I$ V6 X无论如何,测试不同的变体(请使用SQL_NO_CACHE)总是好的,将相关查询转换为联接是一个好习惯。
" `0 v/ I% i3 e4 r我什至会称其为非常有用的做法。: R0 ?2 q" j. f$ X
如果您首先想到了相关查询,则可能不是您主要考虑集合操作,而是考虑过程操作以及处理关系数据库时,完全采用集合是非常有用的数据模型的透视图以及对其的转换。
/ e2 p4 ]' V" x3 w0 p编辑:  就集合运算与过程而言, 过程与关系
( Y- f% h& g. M6 G( t思考归结为某些集合代数表达式中的等价关系,例如,在并集上的选择等同于选择的并集。两者之间没有区别。5 A  v. ~3 j9 o: W
但是,当您比较这两个过程时,例如将选择标准应用到具有make
7 A: g& \% e2 v0 Junion的并集的每个元素上,然后应用选择,则这两个过程是截然不同的过程,它们可能具有非常不同的属性(例如,CPU利用率,I / O,内存)。7 s0 g5 i: a2 r9 q! L" d) J
关系数据库背后的思想是,您不会尝试描述如何获得结果(过程),而只是描述您想要的结果,并且数据库管理系统将决定满足您请求的最佳路径(过程)。这就是为什么SQL被称为第四代语言(4GL)的原因。
6 ]3 P7 [3 z9 z3 e7 R9 B可以帮助您做到这一点的技巧之一是提醒自己,元组没有固有的顺序(集合元素是无序的)。另一个人意识到关系代数非常全面,并且可以将请求(要求)直接转换为SQL(如果模型的语义很好地表示了问题空间,或者换句话说,如果表和关系的名称附带的含义正确完成)
8 S+ u' d  J& Q# K7 y0 i,换句话说,如果您的数据库设计合理)。
9 D7 G, I3 Y( f0 z9 I* N. D* i9 ]因此,您不必思考如何,只需思考什么。2 t# N: b- [: M7 ?
在您的情况下,它只不过是优先于相关查询,因此可能是我没有告诉您任何新内容,但您强调了这一点,因此发表了评论。9 m) e$ g/ D8 w! D" R
我认为,如果您完全满意将查询从一种形式转换为另一种形式的所有规则(诸如分布性之类的规则),则您将不希望使用关联子查询(所有形式都相等)。
: E3 r9 E  U- I+ C* ~  ]& W4 l(注意:上面讨论了理论背景,对于数据库设计很重要;实际上上述概念有所不同-0 R* A6 T# h# ]) |, I
并非所有等效的查询重写都必须以快速执行,因为集群主键确实会使表在磁盘上具有继承顺序,依此类推…但是这些偏差只是偏差;并非所有等效查询都执行得这么快的事实是实际DBMS的缺陷,而不是其背后的概念)
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则