[实验] 两个表关联查询快,还是分开多次连库查询快


背景:

这是最近一直想的一个问题,按之前的经验来判断应该是连表要快一些,那么接下来来个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