看到很多朋友对数据库的理解、认识还是没有突破一个瓶颈,而这个瓶颈往往只是一层窗纸,越过了你将看到一个新世界。 @[8 *G
看到很多朋友对数据库的理解、认识还是没有突破一个瓶颈,而这个瓶颈往往只是一层窗纸,越过了你将看到一个新世界。 @[8 *G
V)ZK5.S[K@
04、05年做项目的时候,用SQL Server 2000,核心表(大部分使用频繁的关键功能每次都要用到)达到了800万数据量,很早以前查过一些相关表,有的达到了3000多万,磁盘使用的光纤盘,100G空间,每周必须备份转移数据,否则100G空间一周会满掉,这个系统几年来,目前仍然保持非常良好的性能。还听说过朋友的SQL Server 2000数据库工作在几十TB的环境下,高并发量,对这种级别的驾驭能力我还是差的很遥远。 coV7z^%
Znw,MC
想当年,也是一提SQL Server,就觉得它的性能没法跟Oracle相比,一提到大数据处理就想到Oracle。自己一路走来,在本地blog上记录了很多优化方面的post,对的错的都有,没有时间系列的整理出来,这篇文章将join方法的概念稍微整理在一起,给大家个参考。通过查资料了解里面提到的各种概念,在实际中不断验证总结,完全可以对数据库一步步深入理解下去的。 aEL|gj6
0 y-j
我只对SQL Server 2000比较了解,但这并不阻碍我在Oracle、MySql进行SQL调优、产品架构,因为在数据库理论原理上,各大数据库基本出入不大,对数据库的深入理解,也不会影响你架构设计思想变坏,相反给你带来的是更深层次的思考。 .wz4 Z6.
%L Z7skl
关于执行计划的说明 $43-qFv+E
&O (5:Oq
在SQL Server查询分析器的Query菜单中选择Show Execution Plan,运行SQL查询语句,在结果窗口中有Grid、Execution Plan、Messages三个Tab。看图形形式的执行计划,顺序是从右到左,这也是执行的顺序。执行计划中的每一个图标表示一个操作,每一个操作都会有一个或多个输入,也会有一个或多个输出。输入和输出,有可能是一个物理数据表、索引数据结构,或者是执行过程中的一些中间结果集/数据结构。鼠标移动到图标上,会显示这个操作的具体信息,例如逻辑和物理操作名称、记录的数量和大小、I/O成本、CPU成本、操作的具体表达式(参数Argument)。鼠标移动到连接箭头上,会显示箭头起始端的操作输出结果集的记录数、记录的大小,一般情况下可以将这个输出结果集理解为箭头结束端的输入。 DFB \>2)gn
K:=i[)S
另外关于执行计划的一些补充说明:1. 执行计划中显示的信息,都是一个“评估”的结果,不是100%准确的信息,例如记录数量是取自统计信息,I/O成本、CPU成本来自执行计划生成过程中基于统计信息等得出的评估结果。2. 执行计划不一定准确,一方面受SQL Server维护的统计信息准确性的影响,另一方面SQL语句编译时刻与执行时刻的环境(内存使用状况、CPU状况等)可能会不一样。 o]r%;%6{\
w^.LR|)
关于统计信息、I/O成本和CPU成本的评估、SQL语句的编译和执行过程,这里不再深入。另外尽管执行计划不一定准确,但它仍是SQL语句分析最重要的依据,因为你可以理解为,绝大部分情况下,SQL Server是以这种方式来执行的。 w7WLy!W,E
PY4%g1=REH
JOIN方法说明 $M f`z
uVO-Z2gX
数据库中,象tableA inner join tableB、tableA left out join tableB这样的SQL语句是如何执行join操作的?就是说SQL Server使用什么算法实现两个表数据的join操作? 1(~NKtQcy
W~fMb=Z&
SQL Server 2000有三种方式:nested loop、merge、hash。Oracle也是使用这三种方式,不过Oracle选择使用nested loop的条件跟SQL Server有点差别,内存管理机制跟SQL Server不一样,因此查看执行计划,Oracle中nested loop运用非常多,而merge和hash方式相对较少,SQL Server中,merge跟hash方式则是非常普遍。 F[o5Tar
7xOG#B`P
以SQL Server 2000为例对这三种方式进行说明,穿插在里面讲解执行计划的一些初级使用。 @uu>uKr=
c&cQ}C},
1. nested loop join cL!`Kpy2
m'6X^$ZB
1.1 示例SQL #S\g'ON
z.b !,t:
select ... from tableA inner join tableB on tableA.col1=tableB.col1 where tableA.col2=? and tableB.col2=?tableA中没有建立任何索引,tableB中在col1上有建立一个主键(聚集索引)。 vzGCmR-&f
z?o_=w<
1.2 算法伪代码描述 k swL M q
j`JUcro_
foreach rowA in tableA where tableA.col2=?{search rowsB from tableB where tableB.col1=rowA.col1 and tableB.col2=? ;if(rowsB.Count<=0)discard rowA ;elseoutput rowA and rowsB ;} d yVD
B=jYCZ
!9JlAjTg
join操作有两个输入,上面例子中tableA是outer input,用于外层循环;tableB是inner input,用于循环内部。下面针对执行计划描述一下SQL Server完成这个操作的具体步骤。 9 v1x`
Yh%ws)L@V#