回答

收藏

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

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

我有一张叫订单的桌子。订单上的一列是customer_id,
0 ~5 F. @( F7 r我有一个名为“ customers”的表,具有10个字段
7 i: Y) O" R/ ]" ]5 l- K5 z2 m给定两个选项,如果我要建立一个订单对象数组并将其嵌入到一个客户对象中,那么我有两个选择。
/ r9 s) u/ n5 O; Q  E' b% O. O! b选项1:
8 ]. d' z- }9 l4 k: M% K一种。首先查询订单表。b。遍历记录并查询人员表以获取人员的记录  O( g9 p% {+ {& Y5 c7 x3 C
这将是这样的:
/ {$ s+ r% R3 V8 b+ }+ i Select * from APplications/ @( b/ G4 g% Y) F" s1 r+ l
Select * from Customer where id = 1) e; f+ L, a, G
Select * from Customer where id = 2
# o7 y; n, H5 l Select * from Customer where id = 32 V( p" v" B! |0 f6 R; e: |
Select * from Customer where id = etc . . .5 F% R5 M. o" Q! a3 f: U
选项2:% h) o/ i/ q1 a% D# {: M
一种。在所有领域参加! p! P  p8 s- j/ [1 H8 J+ d
#2是显而易见的,因为您只执行一个查询,而不是1 + [numberOforders]个查询(可能是数百个或更多)- }1 }: Y4 ]' @# n+ D3 g' R( i
就像这样:
2 |% H" e  o. R; p5 T/ I Select * from Applications a, Customers c+ m+ l: I& n/ j
Innerjoin c.id = a.customerID. q4 [# o8 Y- Y
我的主要问题是,如果我还有10个其他订单表之外的其他表(类似于客户),而您在订单表中有ID,该怎么办?您应该执行一个将这10个表联接起来的查询,还是在某种程度上这样做效率低下:
+ i2 ?+ c/ ~  c5 ^1 x  N任何建议都将有所帮助..是否有任何优化来确保快速性能
' N7 c" K7 K  y+ P% r               
9 `5 @$ S8 n/ U5 a. A# ^1 ?2 k! v解决方案:8 h# c% s) E7 x
                ) M, ]0 o" w- F

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

本版积分规则