sqlserver2K在做JOIN时,它到底是怎样工作的,工作原理是怎样的?

vaccum 2003-03-18 05:38:21
最好能详细些。
谢谢。
...全文
47 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
cdshelf 2003-03-20
  • 打赏
  • 举报
回复
测试报告:

------------------------------------------

环境:P4 2G, 512M RAM,Windows 2000 Server, Sql Server 2000
表一: Po( ID(int PK), Client(int FK), PoDate(DateTime) ) cluster indexed
表二: Client( ID(int PK), Name(nvarchar) ) cluster indexed

Sql 语句:
Select po.PoDate,cl.[Name]
from Po po
inner join Client cl on cl.[ID]=po.Client



大数据量测试结果 (Po 表含 100,000 条记录, Client 含 1000 条记录) :


执行计划被分成三个步骤,


1。 对 Po 表的 clustered index scan (Total Cost: 0.376456, 29%)
Row Count: 100,010
IO Cost: 0.266
CPU Cost: 0.109
Number of Executes: 1

2。 对 Client 表的 clustered index scan (Total Cost: 0.039490, 3%)
Row Count: 1001
IO Cost: 0.0383
CPU Cost: 0.00117
Number of Executes: 1

3。 对两个表的结果进行 Hash Match (Total Cost: 0.852, 67%)
Row Count: 100,010
IO Cost: 0.000000
CPU Cost: 0.852
Number of Executes: 1

查询共耗时: 1秒


小数据量测试结果 (Po 表含 300 条记录, Client 含 40 条记录) :

执行计划被分成三个步骤,

1。 对 Po 表的 clustered index scan (Total Cost: 0.037987, 55%)
Row Count: 300
IO Cost: 0.0187
CPU Cost: 0.000204
Number of Executes: 1

2。 对 Client 表的 clustered index Seek (Total Cost: 0.030288, 44%)
Row Count: 300
IO Cost: 0.00632
CPU Cost: 0.000080
Number of Executes: 300

3。 对两个表的结果进行 Nested Loops (Total Cost: 0.001254, 2%)
Row Count: 300
IO Cost: 0.000000
CPU Cost: 0.00125
Number of Executes: 1

查询共耗时: 少于1秒

结论:

1。 对于庞大数据的查询, Sql Server 的查询优化器会自动调整查询计划,上面三个步骤的 "Number of Executes" 都是 1 ,有点出乎我的预料,这说明,对于大数据量, 查询优化器会

对被查询所有表进行表扫描,将其中一个表的扫描结果生成一个 hash 表,然后,将另一个表的扫描结果与之匹配。而对小数据量查询的时候,查询优化器会先对一个表进行 clustered

index scan ,然后,针对获得的每一行数据,到第二个表中进行 Clustered index seek ,找到的结果同第一个表的结果匹配,所以,我们注意到,小数据量测试中, Client 表的 "Number

of executes" 为 300,说明,查询优化器认为对当前的小数据量,使用循环,开支更小。

2。 从上面的结果可以看到, Index 对提高查询效率具有无可比拟的作用。 不过 index 会影响数据写入的速度,我在随机写入 100,000 条记录的时候,一共花费了 12分钟。

3。 查询优化器非常智能,只要我们的代码符合数据库设计规范,它的执行效率是很出色的。
SophiaWang 2003-03-19
  • 打赏
  • 举报
回复
看看联机帮助吧,上面写得很清楚的!
cdshelf 2003-03-19
  • 打赏
  • 举报
回复
举个例子:
两个表 Po 和 Client
Po 中每条记录中都有 Client 的 ID ,现在要返回所有 Po 记录,记录中要包含 Client 的 名字(而不是 ID)

Select po.PoNo, cl.Name from Po po inner join Client cl on cl.id=po.Client

SQL 的查询优化器会首先对 Po 表进行一个 Table Scan ,然后,对 Client 表进行一个 Table Seek ,查找与 Po.Client 相对应的记录,最后,把这些结果一一对应,合并成一个表。
icevi 2003-03-19
  • 打赏
  • 举报
回复
你可以看下帮助,MSSQL在生成笛卡儿积时有不同的处理方式的,它会自己选择最合适的方式,除非你用join hints强制设定用某种方式。
有下面四种JOIN方式,LOOP 、HASH 、MERGE、REMOTE。每种实际运行时的处理方式会有所不同。
内容比较多,不详说了,最好看看帮助,我电脑上是E文的帮助,就不贴上来了。
大健 2003-03-19
  • 打赏
  • 举报
回复
gz
hillhx 2003-03-19
  • 打赏
  • 举报
回复
JOIN 就是产生笛卡儿积,没什么特别的啊
nik_Amis 2003-03-19
  • 打赏
  • 举报
回复
up
vaccum 2003-03-19
  • 打赏
  • 举报
回复
比如有主表(Emp_ID为主键,IDENTITY),从表(Emp_ID为外键,有INDEX).

如果返回的结果是几万行,能否从理论上推算出JOIN的代价,应该如何计算?

当然哪位DX如果能实际测试,出一个benchmark,我将不胜感激。毕竟事实胜于雄辩。功德一件。
vaccum 2003-03-18
  • 打赏
  • 举报
回复
up

34,872

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧