回答

收藏

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

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

我有一张叫订单的桌子。订单上的一列是customer_id,
) A- k7 u3 L' Z2 M0 o% o我有一个名为“ customers”的表,具有10个字段
! B8 c8 \0 Q7 N0 k* B* K2 t/ B给定两个选项,如果我要建立一个订单对象数组并将其嵌入到一个客户对象中,那么我有两个选择。. H6 g$ p+ l$ B# C) ?4 O4 O
选项1:; q7 y! j  c0 i; }" g% U
一种。首先查询订单表。b。遍历记录并查询人员表以获取人员的记录! ^  i6 K7 r$ h" V9 T6 H
这将是这样的:
/ f( A7 Y4 z/ Q: @ Select * from APplications2 S- p* q0 T0 }5 H
Select * from Customer where id = 1
; o6 `1 I1 ]4 a" x8 x0 W$ c Select * from Customer where id = 2: J. [- Y! i0 W4 _$ y) s) ]
Select * from Customer where id = 3/ h* t; Q8 Q+ ?2 w
Select * from Customer where id = etc . . .+ C, H9 v/ \2 W1 x, Q# c
选项2:
' D3 x0 [5 Z: F2 C$ G" `一种。在所有领域参加
% `7 }9 s1 \1 o0 I- h#2是显而易见的,因为您只执行一个查询,而不是1 + [numberOforders]个查询(可能是数百个或更多)! ~( @! M0 L" R+ k3 }/ l0 F
就像这样:+ `* K/ @0 Q; Q" V5 c
Select * from Applications a, Customers c
6 O7 V1 k; P- c6 @/ e2 f4 G+ i6 N3 T Innerjoin c.id = a.customerID' ^8 s7 y+ C8 Z" ^/ y* j
我的主要问题是,如果我还有10个其他订单表之外的其他表(类似于客户),而您在订单表中有ID,该怎么办?您应该执行一个将这10个表联接起来的查询,还是在某种程度上这样做效率低下:
! k: I9 m. n6 W$ x任何建议都将有所帮助..是否有任何优化来确保快速性能
5 ]1 T0 z9 [/ \5 Q+ m                ' p) ?; U/ }4 s5 p' m
解决方案:
+ K0 _9 [5 U4 @! d3 m                ) f' u' \7 j' C9 _, d/ W% P

8 F0 f+ G. }# f; ]! J2 H1 \4 C8 b# J
2 b. c9 a- q, I% W4 G" x                我同意每个人的观点,即即使有很多表,单联接也可能会更有效率。与在应用程序代码中完成工作相比,这也减少了开发工作量。假定表已正确索引,每个外键列上都有一个索引,并且(当然)每个主键列上都有一个索引。
* K  _4 X2 X3 p8 t" g# j, u: G最好的选择是首先尝试最简单的方法(大连接),然后查看其效果如何。如果运行良好,那就太好了-您已完成。如果执行不佳,请分析查询并查找表中缺少的索引。
* K- }* R% K2 _8 Y' f; w$ n: y由于网络往返次数(如anijhaw所述),您的选择#1不太可能执行良好。有时这称为“选择N + 1”问题-
0 c" u, T* ~! P. d) P) g您执行一个SELECT以获得N个应用程序的列表,然后循环执行N) W6 f' m% E' R: V
SELECTs以获取客户。对于应用程序程序员来说,这种一次记录循环是很自然的。但是当您一次处理整个数据集时,SQL的效果要好得多。% R; V! y' j3 w: T5 ~- g
如果即使索引良好,选项#2还是很慢,则您可能需要研究缓存。您可以在数据库中(使用摘要表或物化/索引视图),在应用程序中(如果有足够的RAM)或专用的缓存服务器(例如memcached)中进行缓存。当然,这取决于查询结果的最新程度。如果所有内容都必须是最新的,则每当底层表更新时,任何高速缓存都必须进行更新-
& G' L  T* X# M: ~& r它变得复杂并且变得不太有用。
6 p3 l6 b9 z0 G  {2 E# g9 d, p但是,这听起来像是报告查询,并且报告通常不需要实时。因此缓存可能可以为您提供帮助。
2 ]% R" B8 W0 T- G& u2 r根据您的DBMS,要考虑的另一件事是此查询对命中同一数据库的其他查询的影响。如果您的DBMS允许读取器阻止编写器,则此查询可能需要很长时间才能运行,因此可能阻止对表的更新。那将是不好的。Oracle没有此问题,在“读取已提交的快照”模式下运行时,SQL
; Q! P& B( F& O5 CServer也没有。我不了解MySQL。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则