在平时的开发中,涉及多表数据联合查询时,一般我都会想当然的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秒
这个,这个,我以为关联表也会像使用游标一样,会更慢些。
难道是选用的表中数据太少了?还是打开数据库连接、关闭数据库连接确实挺耗时间?
也可能是因为在本机测试,数据不多,再者数据库本来就没什么压力,这样的关联查询,在公司服务器上查询,没个好几秒是出不来数据的。
(纯属菜鸟学习体验,如有错误,还请指出,不胜感激!!!)