qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

          關(guān)于SQL一對多關(guān)系轉(zhuǎn)換的效率思考(續(xù))

           之前寫了一篇文章關(guān)于SQL函數(shù)效率的一些測試與思考,在當(dāng)中提到了將數(shù)據(jù)庫中一對多關(guān)系轉(zhuǎn)換為一對一關(guān)系顯示的兩種方法:第一種方法是在數(shù)據(jù)庫中寫一個函數(shù),第二種方法為在程序中獲取表Class與表Student所有數(shù)據(jù),然后對比ClassID。

            那么除了這兩種方法,還有沒有更快、更好的方法呢?在這里我再介紹兩種方法與大家分享、討論

            閑話不多說,下面進入正文。還是那兩張表

            Student:

            Class:

            想要獲得的數(shù)據(jù)效果為

            第三種方法:使用SQL函數(shù)stuff

            SQL語句如下

          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所有數(shù)據(jù),然后對比ClassID)對比效率,輸出結(jié)果如下:

            00:00:00.5497196
            00:00:00.3517834
            效率比1.562665
            =============================
            00:00:01.0181020
            00:00:00.7060913
            效率比1.441884
            =============================
            00:00:01.4912831
            00:00:01.0682834
            效率比1.395962
            =============================
            00:00:01.9636678
            00:00:01.4199062
            效率比1.382956
            =============================
            00:00:02.4391574
            00:00:01.7712431
            效率比1.377088
            =============================
            00:00:02.9111560
            00:00:02.1255719
            效率比1.369587
            =============================
            00:00:03.3923697
            00:00:02.5069699
            效率比1.353175
            =============================
            00:00:03.8671226
            00:00:02.8594541
            效率比1.352399
            =============================
            00:00:04.3314012
            00:00:03.2064415
            效率比1.350844
            =============================
            00:00:04.8019142
            00:00:03.5546490
            效率比1.350883
            =============================

           第一個時間為第二種方法的執(zhí)行時間,第二個時間為第三種方法執(zhí)行時間。每種方法循環(huán)了10次以確保數(shù)據(jù)準(zhǔn)確性

            關(guān)于測試程序代碼在之前的文章中有提到,改一下SQL語句就可以使用了

            數(shù)據(jù)結(jié)果顯示第三種方法要優(yōu)秀不少。至于為什么第三種方法快,我心里已經(jīng)有了個大致的想法,不過因為太難表述了,就懶得浪費口水說了,大家記住結(jié)論就好了

            接下來介紹第四種方法:在SQL中加載程序集,在查詢時調(diào)用程序集

            加載程序集的方法有些難以表述,感興趣的朋友可以自己去查找相關(guān)資料。在此我貼出主要代碼:

          View Code

              /// <summary>
              /// The variable that holds the intermediate result of the concatenation
              /// </summary>
              private StringBuilder intermediateResult;

              /// <summary>
              /// Initialize the internal data structures
              /// </summary>
              public void Init()
              {
                  this.intermediateResult = new StringBuilder();
              }

              /// <summary>
              /// Accumulate the next value, not if the value is null
              /// </summary>
              /// <param name="value"></param>
              public void Accumulate(SqlString value)
              {
                  if (value.IsNull)
                  {
                      return;
                  }

                  this.intermediateResult.Append(value.Value).Append(',');
              }

              /// <summary>
              /// Merge the partially computed aggregate with this aggregate.
              /// </summary>
              /// <param name="other"></param>
              public void Merge(Concatenate other)
              {
                  this.intermediateResult.Append(other.intermediateResult);
              }

              /// <summary>
              /// Called at the end of aggregation, to return the results of the aggregation.
              /// </summary>
              /// <returns></returns>
              public SqlString Terminate()
              {
                  string output = string.Empty;
                  //delete the trailing comma, if any
                  if (this.intermediateResult != null
                      && this.intermediateResult.Length > 0)
                  {
                      output = this.intermediateResult.ToString(0, this.intermediateResult.Length - 1);
                  }

                  return new SqlString(output);
              }

              public void Read(BinaryReader r)
              {
                  intermediateResult = new StringBuilder(r.ReadString());
              }

              public void Write(BinaryWriter w)
              {
                  w.Write(this.intermediateResult.ToString());
              }

            這個方法比第三種方法快得不多,大概只有5%到10%的性能提升,但是這種方法十分優(yōu)雅,我竊以為這種方法是解決一對多關(guān)系轉(zhuǎn)換一對一方法中最好的方法

            PS:最近太懶了,都沒有來寫東西。罪過罪過

            再PS:想吐槽一下,最近園子里幾個小妹子寫的生活上的雜七雜八的東西居然引起了那么多人的追捧,而真正的技術(shù)貼卻是無人問津,不得不說是一種悲哀

            再再PS:歡迎留言討論,歡迎轉(zhuǎn)載。不足之處望海涵

          posted on 2012-05-24 09:35 順其自然EVO 閱讀(191) 評論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫

          <2012年5月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 托里县| 永川市| 米林县| 凯里市| 施甸县| 涡阳县| 遵义县| 木兰县| 余江县| 晋江市| 大悟县| 揭东县| 连南| 中超| 房产| 隆林| 皮山县| 嘉义县| 遵义县| 泗阳县| 调兵山市| 清苑县| 安宁市| 天台县| 三都| 甘孜县| 左权县| 萨嘎县| 三明市| 理塘县| 精河县| 三亚市| 公主岭市| 古丈县| 城市| 杭州市| 宝清县| 怀远县| 漳平市| 巨野县| 丰顺县|