查询数据量大时,你会选择关联表查询还是循环中依个查询?

在平时的开发中,涉及多表数据联合查询时,一般我都会想当然的Inner Join、Left Join,也经常出现数据量一大查询就特别慢的问题。
刚开始还没在意,想当然的以为,数量大了,查询慢是正常的。
可又想了一下,对于MSSQL来说,40多万也不算很大啊。。。
 
 
今天突然想了下,如果不关联表,而是在循环中,需要时再查询数据库,获取其他表的数据。
 
 
以我目前对SQL的理解:
   1、数据量大时,多表关联查询效率确实是不怎么样,还要考虑分页,那就更闹心了。。。
  2、循环中单个查询,如果是在C#代码中查询,每次查询都要打开数据库连接、关闭数据库连接,再将数据映射到实体类中,好像效率也不怎么样。。。
  3、单个查询的话,一般都是根据主键查询,主键上有索引,所以,速度应该会很快。
  4、考虑到程序的可扩展性及可维护性的话,没得说,肯定用单个查询,而不是多表查询,面向对象嘛。。。
 
 
不纠结了,亲自试验下吧:
 
 
首先看看在游标中,关联表循环和循环中再查询单个数据比较:
(PS:Order表中数据共5000多一点,Member表中数据近16000)
 
 
SQL代码 关联表
 1 Declare@idxint,@idxCountint,@MbCdvarchar(20)
2 Set@idxCount=0
3
4 Declare Cur_Test CursorFor
5 Select M.MB_CD FromOrder O InnerJoin Member M On O.MB_CD=M.MB_CD
6
7 Open Cur_Test
8 FetchNextFrom Cur_Test Into@MbCd
9
10 While (@@FETCH_STATUS=0)
11 Begin
12 Set@idx=1
13 Set@idxCount=@idxCount+@idx
14
15 FetchNextFrom Cur_Test Into@MbCd
16 End
17
18 Close Cur_Test
19 DEALLOCATE Cur_Test
20
21 print@idxCount

执行时间:34秒
 

SQL代码 不关联表
 1 Declare@idxint,@idxCountint,@MbCdvarchar(20)
2 Set@idxCount=0
3
4 Declare Cur_Test CursorFor
5 Select MB_CD FromORDER
6
7 Open Cur_Test
8 FetchNextFrom Cur_Test Into@MbCd
9
10 While (@@FETCH_STATUS=0)
11 Begin
12 Set@idx=0
13 Select@idx=COUNT(*) From MEMBER Where MB_CD=@MbCd
14 Set@idxCount=@idxCount+@idx
15
16 FetchNextFrom Cur_Test Into@MbCd
17 End
18
19 Close Cur_Test
20 DEALLOCATE Cur_Test
21
22 print@idxCount

 

  

 

执行时间:18秒

 
 
确实,不关联表快了将近一倍。
 
不过,考虑到实际使用中,如果是代码中循环执行查询语句去查询单个数据,打开数据库连接、关闭数据库连接也需要消耗时间,而在游标中是不需要的,所以,也在C#中测试了一下。
 
首先是未关联表查询数据,代码如下:
 
C#代码 关联表
 1 int intIdxCount =0;
2
3 DateTime dtmBegin = DateTime.Now;
4 using (DataTable dtList =new SqlDBOperator().exeSqlForDataTable("Select M.MB_CD,O.ORD_NO From ORDER O Inner Join MEMBER M On M.MB_CD=O.MB_CD"))
5 {
6 foreach (DataRow dr in dtList.Rows)
7 {
8 intIdxCount +=1;
9 }
10 }
11 DateTime dtmEnd = DateTime.Now;
12
13 this.litlMsg.Text ="开始执行:"+ dtmBegin.ToString() +"<br/>结束执行:"+ dtmEnd.ToString() +"<br/>";

执行结果:

  开始执行:2011/7/19 22:15:31

  结束执行:2011/7/19 22:15:31 

  大约 0 秒

 

C#代码 不关联表
 1         DataTable dtTemp =new DataTable();
2
3 DateTime dtmBegin = DateTime.Now;
4 using (DataTable dtList =new SqlDBOperator().exeSqlForDataTable("Select MB_CD From ORDER"))
5 {
6 foreach (DataRow dr in dtList.Rows)
7 {
8 dtTemp =new SqlDBOperator().exeSqlForDataTable("select count(*) From MEMBER where MB_CD='"+ dr["MB_CD"].ToString().Trim() +"'");
9 }
10 }
11 DateTime dtmEnd = DateTime.Now;
12
13 this.litlMsg.Text ="开始执行:"+ dtmBegin.ToString() +"<br/>结束执行:"+dtmEnd.ToString();

 

  

 

执行结果:

  开始执行:2011/7/19 21:56:22

  结束执行:2011/7/19 21:56:43 

  大约21秒

 

这个,这个,我以为关联表也会像使用游标一样,会更慢些。

难道是选用的表中数据太少了?还是打开数据库连接、关闭数据库连接确实挺耗时间?

也可能是因为在本机测试,数据不多,再者数据库本来就没什么压力,这样的关联查询,在公司服务器上查询,没个好几秒是出不来数据的。

(纯属菜鸟学习体验,如有错误,还请指出,不胜感激!!!)

转载于:https://www.cnblogs.com/uphenson/archive/2011/07/19/2111145.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值