现在的位置: 首页 > 综合 > 正文

SQL数据库使用JOIN的优化方法

2018年02月01日 ⁄ 综合 ⁄ 共 1969字 ⁄ 字号 评论关闭
很早以前,也是一提到SQL Server,就觉得它的性能没法跟Oracle相比,一提到大数据处理就想到Oracle。自己一路走来,在本地blog上记录了很多优化方面的 post,对的错的都有,没有时间系列的整理出来,这篇文章将join方法的概念稍微整理在一起,给大家个参考。通过查资料了解里面提到的各种概念,在实 际中不断验证总结,完全可以对数据库一步步深入理解下去的。

  我只对SQL Server 2000比较了解,但这并不阻碍我在Oracle、MySql进行SQL调优、产品架构,因为在数据库理论原理上,各大数据库基本出入不大,对数据库的深入理解,也不会影响你架构设计思想变坏,相反给你带来的是更深层次的思考。

  关于执行计划的说明

  在SQL Server查询分析器的Query菜单中选择Show Execution Plan,运行SQL查询语句,在结果窗口中有Grid、Execution Plan、Messages三个Tab。看图形形式的执行计划,顺序是从右到左,这也是执行的顺序。执行计划中的每一个图标表示一个操作,每一个操作都会 有一个或多个输入,也会有一个或多个输出。输入和输出,有可能是一个物理数据表、索引数据结构,或者是执行过程中的一些中间结果集/数据结构。鼠标移动到 图标上,会显示这个操作的具体信息,例如逻辑和物理操作名称、记录的数量和大小、I/O成本、CPU成本、操作的具体表达式(参数Argument)。鼠 标移动到连接箭头上,会显示箭头起始端的操作输出结果集的记录数、记录的大小,一般情况下可以将这个输出结果集理解为箭头结束端的输入。

  另 外关于执行计划的一些补充说明:1. 执行计划中显示的信息,都是一个“评估”的结果,不是100%准确的信息,例如记录数量是取自统计信息,I/O成本、CPU成本来自执行计划生成过程中基 于统计信息等得出的评估结果。2. 执行计划不一定准确,一方面受SQL Server维护的统计信息准确性的影响,另一方面SQL语句编译时刻与执行时刻的环境(内存使用状况、CPU状况等)可能会不一样。

  关于统计信息、I/O成本和CPU成本的评估、SQL语句的编译和执行过程,这里不再深入。另外尽管执行计划不一定准确,但它仍是SQL语句分析最重要的依据,因为你可以理解为,绝大部分情况下,SQL Server是以这种方式来执行的。

  JOIN方法说明

  数据库中,象tableA inner join tableB、tableA left out join tableB这样的SQL语句是如何执行join操作的?就是说SQL Server使用什么算法实现两个表数据的join操作?

  SQL Server 2000有三种方式:nested loop、merge、hash。Oracle也是使用这三种方式,不过Oracle选择使用nested loop的条件跟SQL Server有点差别,内存管理机制跟SQL Server不一样,因此查看执行计划,Oracle中nested loop运用非常多,而merge和hash方式相对较少,SQL Server中,merge跟hash方式则是非常普遍。

  以SQL Server 2000为例对这三种方式进行说明,穿插在里面讲解执行计划的一些初级使用。

1. nested loop join
1.1 示例SQL

select ... from tableA inner join tableB on tableA.col1=tableB.col1 where tableA.col2=? and tableB.col2=?tableA中没有建立任何索引,tableB中在col1上有建立一个主键(聚集索引)。

  1.2 算法伪代码描述
  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 ; }

  join操作有两个输入,上面例子中tableA是outer input,用于外层循环;tableB是inner input,用于循环内部。下面针对执行计划描述一下SQL Server完成这个操作的具体步骤。 %. ^ g.L
2vt [ AhVA
1.3 查看执行计划方法
移到文章最前面。
  1.4 执行步骤
  下 面是示例SQL的执行计划图。 nested loop操作的右边,位于上面的是outer input,位于下面的是inner input。你不能够根据join中哪个表出现在前面来确定outer input和inner input关系,而必须从执行计划中来确定,因为SQL Server会自动选择哪个作为inner input。 

抱歉!评论已关闭.