关于SQL一对多关系转换的效率思考(续)

上一篇 / 下一篇  2012-05-24 10:17:10 / 个人分类:数据库

之前写了一篇文章关于SQL函数效率的一些测试与思考,在当中提到了将数据库中一对多关系转换为一对一关系显示的两种方法:第一种方法是在数据库中写一个函数,第二种方法为在程序中获取表Class与表Student所有数据,然后对比ClassID。51Testing软件测试网{9Eb%u {Qe

  那么除了这两种方法,还有没有更快、更好的方法呢?在这里我再介绍两种方法与大家分享、讨论

S` S0j:Qb QU4@#ZSbu051Testing软件测试网J:K$l;C%w

  闲话不多说,下面进入正文。还是那两张表

D!|c)H_O(d0

R6eGy-ypVp4C0  Student:

:MZlD^^:S*m0

51Testing软件测试网"Ui,H uF*[M UMv9Y

  Class:

)N"naUFB E_0

u.yA(qEh0

  想要获得的数据效果为

b SUHl0

8f [s|5~-r4B0

  第三种方法:使用SQL函数stuff

8?0^L-[9|/K H0

  SQL语句如下

4FwsJA8F2kFYZ0
SELECT C.ID, C.ClassName,stuff((select ',' + S.StuName from dbo.Student S where S.ClassID = C.ID for xml path('')),1,1,'')as stuName FROM Class C

  将第三种方法与第二种方法(在程序中获取表Class与表Student所有数据,然后对比ClassID)对比效率,输出结果如下:

#gVw5bu7DG0

  00:00:00.549719651Testing软件测试网+cy]y%o$|E;O
  00:00:00.351783451Testing软件测试网$fx:r&C-D8qJ
  效率比1.56266551Testing软件测试网Et yTG7{*|
  =============================51Testing软件测试网}$a/~6D-HU
  00:00:01.0181020
O]t@/[ Z%Z0  00:00:00.706091351Testing软件测试网n6hl.z2f0k b4} KP
  效率比1.441884
&O q"v9B9n,h0  =============================
9_1G"jAX&j0  00:00:01.491283151Testing软件测试网P4Oq| z1~"cD
  00:00:01.0682834
Y9|HnS(g$Z eB0  效率比1.39596251Testing软件测试网5` W L5` Ia;p})c
  =============================
|&V2uUqxl0  00:00:01.9636678
TMlDO,h0  00:00:01.4199062
oP3D-B.P IpO*n0  效率比1.382956
4`H&xf,q;Hf0  =============================
z%NU#X K*N%d0  00:00:02.439157451Testing软件测试网6t&O M`VlK
  00:00:01.771243151Testing软件测试网$G}(zXR#cWLx
  效率比1.37708851Testing软件测试网`5U3@h{{6FT[i
  =============================
]:Fz9_+P~)W1~!_0  00:00:02.9111560
MTG1\As8i.E0  00:00:02.1255719
Fb L3E5e2HbR[2c0  效率比1.369587
p&\2| lt {7})\:Z0  =============================
T,X5I@([ ~`0  00:00:03.3923697
7Q&g#s2pw1y0  00:00:02.506969951Testing软件测试网3twm,I-t~rO
  效率比1.35317551Testing软件测试网4eI BP8\}5{
  =============================51Testing软件测试网s5]t;k~
  00:00:03.8671226
iT GN [0  00:00:02.859454151Testing软件测试网-D:xD E+l
  效率比1.352399
"a,gv5w{a0  =============================
:T"Z.b"BE%p1W.`6R0  00:00:04.331401251Testing软件测试网.qy8Mwl0e H+g
  00:00:03.2064415
m)U&_y_YV0  效率比1.350844
@wK'v~0  =============================
` PA-iTJ.RU!S#O*Jm0  00:00:04.8019142
u/WL[m]R0  00:00:03.5546490
k8g i |zA4f-N v0  效率比1.350883
K/oS M+gW W.C1s#dbv0  =============================

C%I?)Tf*u0

第一个时间为第二种方法的执行时间,第二个时间为第三种方法执行时间。每种方法循环了10次以确保数据准确性51Testing软件测试网f-i&JHR7V#|5DH

j[~nWo8[8y`SI0  关于测试程序代码在之前的文章中有提到,改一下SQL语句就可以使用了

6`vDnU051Testing软件测试网?1NR f&d7H2cz&s

  数据结果显示第三种方法要优秀不少。至于为什么第三种方法快,我心里已经有了个大致的想法,不过因为太难表述了,就懒得浪费口水说了,大家记住结论就好了51Testing软件测试网*v5c$[8I2f7a

51Testing软件测试网2t_p.jQ HHm\

  接下来介绍第四种方法:在SQL中加载程序集,在查询时调用程序集

m-x8F9Nh7W0

y-Pv!b `0  加载程序集的方法有些难以表述,感兴趣的朋友可以自己去查找相关资料。在此我贴出主要代码:51Testing软件测试网 W1c8e1h%a2c

51Testing软件测试网.PW'C"Rz&OE0`o

3Z*X)}ZrGR0
51Testing软件测试网n'C.g+s%m'?t

View Code51Testing软件测试网Bx*jsS1f'Y+`

&e1z1{4M;^z0    /// <summary>51Testing软件测试网@M7R~PC ]C}R
    /// The variable that holds the intermediate result of the concatenation
$~'kDT8LE.g0    /// </summary>
F'QB1j.Vz&z9@mx5s0    private StringBuilder intermediateResult;
51Testing软件测试网 Rt0Hs \?3l

`,I-d)Lq+u@U8B0    /// <summary>51Testing软件测试网 y#N2V v;q?T;V+z
    /// Initialize the internal data structures
%P%Q-zv"|C[bj0    /// </summary>51Testing软件测试网2dpuCz,| ~5U
    public void Init()
BP8B? h(h|"x f7o"\0    {51Testing软件测试网 w4S8Y5EcWA4\Kzm
        this.intermediateResult = new StringBuilder();51Testing软件测试网V,g/D{S(G/_6Gn,]
    }

*TH3o;F4N,|+DC051Testing软件测试网(vY+a.t5n#v/hTM3ce)B

    /// <summary>51Testing软件测试网} z wEH0_.a$a i
    /// Accumulate the next value, not if the value is null51Testing软件测试网o9Q-Q Fp-l2^_a
    /// </summary>51Testing软件测试网w~x?)L!O!le
    /// <param name="value"></param>51Testing软件测试网Zf5jU:B9^,{*}"Qr?
    public void Accumulate(SqlString value)
g3r'}3`;H*b q,a0    {
K&msCF^ `j|+d0        if (value.IsNull)51Testing软件测试网f ]&cXuQ
        {
~4Pef6`C&h0            return;
+`f)dLuB^0        }

o8W(S v2CX s0Yf051Testing软件测试网,u.I5Z&x%OD C

        this.intermediateResult.Append(value.Value).Append(',');51Testing软件测试网[9d(r(Y/veX8J
    }

rkV3s*w4[oU.E051Testing软件测试网.n`_6s#uk

    /// <summary>
m0@Sq(W1V wL0    /// Merge the partially computed aggregate with this aggregate.51Testing软件测试网 Z+f2@/SB"J[s
    /// </summary>
J6v V(W hd!Vx0    /// <param name="other"></param>51Testing软件测试网 H3RHX zC:J a0W8S
    public void Merge(Concatenate other)51Testing软件测试网r&F ~Kwo|/i
    {
frc?.}p5j0        this.intermediateResult.Append(other.intermediateResult);51Testing软件测试网`,vCq$GO/l\
    }
51Testing软件测试网QVZ3VE

8tOo~:iu3yMN0    /// <summary>51Testing软件测试网(H1Yz d(j1h H C@T)t0|
    /// Called at the end of aggregation, to return the results of the aggregation.51Testing软件测试网1Kx]8r3mp
    /// </summary>
} c|6eA*a u8H U0    /// <returns></returns>51Testing软件测试网`2c&mAC-X
    public SqlString Terminate()
U$h2?*JJZ{,w0    {51Testing软件测试网0k GR$r#ei|n|
        string utput = string.Empty;
W p7kAn(g4t0        //delete the trailing comma, if any
%m l!U7\wV-K0        if (this.intermediateResult != null
zS}T*y}"d0            && this.intermediateResult.Length > 0)
J;zd%^6j~e0        {
,v,R!Kvg C Q[0            utput = this.intermediateResult.ToString(0, this.intermediateResult.Length - 1);
G)T%O$wsku(A0        }

Nz eNn4`9fGw051Testing软件测试网 xmT:@k

        return new SqlString(output);
%q?2zp(B A0    }

e O_l,? UAH0

@4t#q-K4t:cv0    public void Read(BinaryReader r)
6I/] [*A`&w+XJydFL[0    {
`-n `7Ve0s%}F0        intermediateResult = new StringBuilder(r.ReadString());
Hgc'P)V;J!IX0    }
51Testing软件测试网q/ntBD/k"y,UF\)Y

Q.yy S Q@/@x0    public void Write(BinaryWriter w)
KS$}~2Eg J-Wn0    {51Testing软件测试网4ZJ9A}h"nU*s
        w.Write(this.intermediateResult.ToString());
?"u"v*dN9N0    }
51Testing软件测试网$J@\~1|6S O,f

51Testing软件测试网5F*H3h3NFD7B;D

  这个方法比第三种方法快得不多,大概只有5%到10%的性能提升,但是这种方法十分优雅,我窃以为这种方法是解决一对多关系转换一对一方法中最好的方法51Testing软件测试网"gYe%i7_m+l6s X

51Testing软件测试网4e$`#bI5W T3_5a

  PS:最近太懒了,都没有来写东西。罪过罪过

f5c%l B,q0

7?&|MW,X9Um0  再PS:想吐槽一下,最近园子里几个小妹子写的生活上的杂七杂八的东西居然引起了那么多人的追捧,而真正的技术贴却是无人问津,不得不说是一种悲哀51Testing软件测试网y5Z;m)@H!^

f@$jS;@W&[0  再再PS:欢迎留言讨论,欢迎转载。不足之处望海涵

(M k9P5jQN^sR-{0

TAG:

 

评分:0

我来说两句

Open Toolbar