回答

收藏

一个大联接或多个查询哪个提供更好的性能?

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

我有一张叫订单的桌子。订单上的一列是customer_id,$ U9 V3 c; ]: z6 \
我有一个名为“ customers”的表,具有10个字段1 j3 `4 m/ o& [! [* T7 i8 y  n, g
给定两个选项,如果我要建立一个订单对象数组并将其嵌入到一个客户对象中,那么我有两个选择。
% P. j6 e) A$ }! U# J6 n* Y8 x选项1:
" E$ H' D' D' D: v一种。首先查询订单表。b。遍历记录并查询人员表以获取人员的记录6 y6 ^+ b! I/ B! I0 L& [$ B
这将是这样的:
4 z! i) C1 m# U8 I! N, n Select * from APplications
- T% ~, s  [% ?# t, ]- ]7 _ Select * from Customer where id = 1
9 k# n. a( Y! L- x Select * from Customer where id = 2$ Z# }' r! z4 J7 V5 X* \( `
Select * from Customer where id = 3
  \  L- R5 j; \! u) L  B7 p/ V Select * from Customer where id = etc . . .  v! b+ {2 ?+ T3 F* p  s0 d
选项2:
- u1 z$ q5 @) \一种。在所有领域参加
% r1 I0 `* I$ E- L$ H#2是显而易见的,因为您只执行一个查询,而不是1 + [numberOforders]个查询(可能是数百个或更多)
# y6 U; ~4 Q, F# X$ q, X就像这样:
! G9 v" J, {* o! B: @& b! z& m Select * from Applications a, Customers c: P! @* Y0 h2 V9 k; b( [) U4 e7 O6 x
Innerjoin c.id = a.customerID
- ~) n7 w# f: I; z- K我的主要问题是,如果我还有10个其他订单表之外的其他表(类似于客户),而您在订单表中有ID,该怎么办?您应该执行一个将这10个表联接起来的查询,还是在某种程度上这样做效率低下:
& }9 y9 e& @# e. ~+ Y4 {8 p任何建议都将有所帮助..是否有任何优化来确保快速性能
7 g5 T7 T) Z* j2 z               
$ Q4 T+ z5 G& o! ^7 j/ y: R- L解决方案:1 }4 Y0 A  i7 j. L
                1 l0 S0 \# I- m1 _) t

4 {7 a7 g3 e/ O6 F& @( J' ~4 |1 x
( G8 T- m% @! B' O+ R3 K$ l                我同意每个人的观点,即即使有很多表,单联接也可能会更有效率。与在应用程序代码中完成工作相比,这也减少了开发工作量。假定表已正确索引,每个外键列上都有一个索引,并且(当然)每个主键列上都有一个索引。8 |9 Y/ t: {9 ]# U: G: t7 z
最好的选择是首先尝试最简单的方法(大连接),然后查看其效果如何。如果运行良好,那就太好了-您已完成。如果执行不佳,请分析查询并查找表中缺少的索引。
6 m* {3 X6 a! J4 [* Z由于网络往返次数(如anijhaw所述),您的选择#1不太可能执行良好。有时这称为“选择N + 1”问题-
. l! n5 L( m, Y) \2 Y- q您执行一个SELECT以获得N个应用程序的列表,然后循环执行N/ y: g& v; M3 u3 o
SELECTs以获取客户。对于应用程序程序员来说,这种一次记录循环是很自然的。但是当您一次处理整个数据集时,SQL的效果要好得多。
) q3 l( z2 V. v* B如果即使索引良好,选项#2还是很慢,则您可能需要研究缓存。您可以在数据库中(使用摘要表或物化/索引视图),在应用程序中(如果有足够的RAM)或专用的缓存服务器(例如memcached)中进行缓存。当然,这取决于查询结果的最新程度。如果所有内容都必须是最新的,则每当底层表更新时,任何高速缓存都必须进行更新-( b: j7 P; [) Q
它变得复杂并且变得不太有用。! H$ M- Z* K$ A, [9 [1 p$ Y9 X7 C+ A
但是,这听起来像是报告查询,并且报告通常不需要实时。因此缓存可能可以为您提供帮助。
. N  h4 H4 a/ L" o: y根据您的DBMS,要考虑的另一件事是此查询对命中同一数据库的其他查询的影响。如果您的DBMS允许读取器阻止编写器,则此查询可能需要很长时间才能运行,因此可能阻止对表的更新。那将是不好的。Oracle没有此问题,在“读取已提交的快照”模式下运行时,SQL7 r: v7 Q/ ~* L( U& A, d! G8 B6 @/ T
Server也没有。我不了解MySQL。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则