[實驗] 兩個表關聯查詢快,還是分開多次連庫查詢快


背景:

這是最近一直想的一個問題,按之前的經驗來判斷應該是連表要快一些,那么接下來來個Demo測試一下。本次測試采取兩張表(Order表-20w左右數據量,OrderLog-105w左右數據量),實驗代碼見附錄
 
實驗:
1. 先來測試左連操作的情況
2. 接下來看下兩次連庫的情況
3. 注意:兩次查詢注意清除數據庫緩存,以免影響查詢結果
 
DBCC DROPCLEANBUFFERS 
從緩沖池中刪除所有清除緩沖區。 
DBCC FREEPROCCACHE 
從過程緩存中刪除所有元素。 
DBCC FREESYSTEMCACHE 
從所有緩存中釋放所有未使用的緩存條目。
 
4. 試着 在OrderLog表中添加非聚集索引(Index_OrderLog_OrderID)后再來看查詢結果
沒錯,不到1秒就出結果了,強大的索引呀
分析:
兩個表都有索引,都是以ID為聚集索引,看上面的結果,貌似差不多的樣子,的確也差不多,不過根據現實中的經驗一般都會 用連表,而不是去多次去連庫查詢,我覺得原因有以下幾個吧
1. 每次連庫都會產生較大的性能消耗(相比較於查詢數據而言)
2. 多次連庫也會存在不穩定性,如果其中的一次連庫失敗,那么最終的結果就不會出來
3. 連表查詢如果遇到性能問題可以建索引來解決,而連庫的性能消耗大了很難去解決(受外部網絡影響)
 
 
附錄:
private static string connectionStr = "data source=192.168.6.37;database=Tidebuy;uid=sa;pwd=123456;";
        private static string idStr = @"73498,73514,73546,73716,73798,74029,74042";
        static void Main(string[] args)
        {
            #region 生成數據
            //for (int index = 100001; index <=200000; index++)
            //{

            //    Test1 entity = new Test1()
            //    {
            //        Name = "Test" + index.ToString(),
            //        Description = ""
            //    };
            //    Encoding gb = System.Text.Encoding.GetEncoding("GB2312");

            //    //調用函數產生4個隨機中文漢字編碼
            //    object[] bytes = CreateRegionCode(150);
            //    string number = index % 3 == 0 ? index.ToString() : "";
            //    //根據漢字編碼的字節數組解碼出中文漢字
            //    for (int i = 0; i < 10; i++)
            //    {
            //        entity.Description += gb.GetString((byte[])Convert.ChangeType(bytes[i], typeof(byte[]))) + number;
            //    }
            //    if (InsertData(entity, connectionStr))
            //    {
            //        //輸出的控制台
            //        Console.WriteLine(entity.Name);
            //    }
            //}
            #endregion  

            DateTime start = DateTime.Now;
            Console.WriteLine("左連操作執行開始:" + start.ToString("yyyy-MM-dd HH:mm:ss fff"));


            int count = SelectFromTB_OrderLeftJoinTB_OrderLog();
            Console.WriteLine("左連操作結果:" + count);


            DateTime end = DateTime.Now;
            Console.WriteLine("左連操作執行結束:" + end.ToString("yyyy-MM-dd HH:mm:ss fff"));
            Console.WriteLine("耗時:" + (end - start).ToString());

            //DateTime start = DateTime.Now;
            //Console.WriteLine("連庫操作執行開始:" + start.ToString("yyyy-MM-dd HH:mm:ss fff"));


            //string orderIdStr = SelectFromTB_Order();
            //int count = SelectFromTB_OrderLog(orderIdStr);
            //Console.WriteLine("連庫操作結果:" + count);


            //DateTime end = DateTime.Now;
            //Console.WriteLine("連庫操作執行結束:" + end.ToString("yyyy-MM-dd HH:mm:ss fff"));
            //Console.WriteLine("耗時:" + (end - start).ToString() + "\r\n\r\n");


        }

        /// <summary>
        /// 20w數據的表
        /// </summary>
        /// <returns></returns>
        public static string SelectFromTB_Order()
        {
            string sql = string.Format(@"SELECT * FROM TB_Order WHERE ID IN({0})", idStr);
            DataTable table = new DataTable();
            TbDatabase.Fill(connectionStr, sql,table);

            StringBuilder orderIdStr = new StringBuilder();

            if (table!=null&&table.Rows.Count>0)
            {
                foreach (DataRow row in table.Rows)
                {
                    orderIdStr.Append(row["ID"].ToString() + ",");
                }
            }
            if (orderIdStr.Length>0)
            {
                return orderIdStr.ToString().Substring(0, orderIdStr.Length - 1);
            }
            else
            {
                return "";
            }
        }
        /// <summary>
        /// 105w的數據量
        /// </summary>
        /// <param name="orderIdStr"></param>
        /// <returns></returns>
        public static int SelectFromTB_OrderLog(string orderIdStr)
        {
            string sql = string.Format(@"SELECT * FROM TB_OrderLog WHERE OrderID IN({0})", orderIdStr);
            DataTable table = new DataTable();
            TbDatabase.Fill(connectionStr, sql, table);

            if (table != null && table.Rows.Count > 0)
            {
                return table.Rows.Count;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 20w*105w左連
        /// </summary>
        /// <returns></returns>
        public static int SelectFromTB_OrderLeftJoinTB_OrderLog()
        {
            string sql = string.Format(@"SELECT * FROM TB_OrderLog ol WITH(NOLOCK) LEFT JOIN TB_Order o ON ol.[OrderID]=o.[ID]
                WHERE o.ID IN({0})",idStr);
            DataTable table = new DataTable();
            TbDatabase.Fill(connectionStr, sql, table);

            if (table != null && table.Rows.Count > 0)
            {
                return table.Rows.Count;
            }
            else
            {
                return 0;
            }
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM