SQL Server与Oracle数据库在查询优化上的差异

上一篇 / 下一篇  2012-04-28 10:07:36 / 个人分类:数据库

一般来说,Oracle数据库在大型数据环境下,其运行性能比SQLServer数据库效率要高。单从查询优化上讲,两者就有比较大的差异。下面,笔者将数据库查询优化的差异做一个描述,若有不准确的地方,还请大家批评指教。

i%JuzL1|tc y0  一、在数据库排序查询优化上的差异。51Testing软件测试网W C(I ^Ykd

Q d] EJ1l(m0g0  在讲解这个内容之前,为了读者能够清楚我讲的内容,我要先谈一个概念。命中率,它是指从内存中取得数据而不从磁盘中取得数据的比率。我们在前几篇文章中 都提到过,当在数据库中查询数据时,数据库服务器都是先从内存中寻找数据。只有在内存中数据不存在的情况下,才会去读取数据库文件的内容。而且,从内存中 查询数据要比在数据库文件中查询数据效率高得多。从这方面讲,我们若能够提高这个查询的命中率,则显然可以提高数据库系统的查询效率。

GXn @lw C9w051Testing软件测试网U iZ|#tK4BP

  虽然SQL Server与Oracle在这方面都有所作为,但是,笔者认为,Oracle数据库在这方面的优势比较明显。特别是Oracle数据库采用了临时段的管理机制,明显提高了数据库查询的命中率。51Testing软件测试网3@M*Jc5h,el+t(D

51Testing软件测试网XBx3Ob6BAc0^

   那什么叫作数据库的临时段呢?假设当我们刚查完员工信息表后,此时,员工信息表的内容就存在数据库服务器的内存中。此时,我们需要对这个表进行排序查 询,如我们希望查询出工龄超过两年的员工,并且按工龄的长短进行排序。此时,Oracle数据库服务器会设法在内存中排序区对所有行进行排序。而这个排序 区的大小则有数据库的初始化文件init.ora进行确定。当这个排序区不够大,不能够容纳我们所查询出来的员工信息记录数时,数据库就会在排序操作期 间,在数据库服务器中开辟临时段。很明显,在查询操作过程中,若开辟临时段的话,会减低数据库的命中率,降低排序查询的效率。我们现在希望这个排序能够在 内存中完成,而不需要开辟额外的临时段,如此的话,就可以消除向临时段写数据的开销,提高排序查询的效率。所以,当我们数据库中的数据比较庞大时,我们可 以考虑增加这个排序区的长度,以避免临时段的需要。正是这个临时段的问题,如我们刚查询完员工信息表,查询完成之后,再对该表进行排序查询,就觉得好像仍 然是新的查询一样。其实,这个排序查询的问题,我们可以通过一定的方法对此进行优化,以提高排序查询的效率。51Testing软件测试网'r*o U4})n(B.@q:UD

6t6x0]+fx.^ r0  修改方法:51Testing软件测试网?$Z5Q'l,@!n*f

ki!|6?8cL7Qr0  第一步:先利用查询语句判断,是否有临时段需求的产生。51Testing软件测试网 wb7M| nGb

51Testing软件测试网2RUX*}8s&U$A p

select * from v$sysstat where name='dtmfg(disk)' or name='dtmfg(memory)';51Testing软件测试网9T:k#d:kr g$o

Nw{"t(d+};[0  如我们可以定时利用以上语句,来查询是否有临时段需求的产生。这条语句中,dtmfg是具体的数据库实例名,我们只需要修改这个名字,就可以查询到我们需要的内容。若在查询结果中,发现有临时段需求产生的话,则就需要考虑修改相关的配置文件,以优化排序查询性能。51Testing软件测试网'o vdR*W"jG2Jl5e}

51Testing软件测试网F:s0aO TtT#f

  第二步:修改参数配置文件。

A:lJr8au{~ZC051Testing软件测试网%]$b'Q nC5eK}Q`

  我们需要修改inint.ora文件,修改里面的SORT-AREA-SIZE的值。不过,修改这个配置文件之后,还必须重新启动数据库才会生效。一般情况下,数据库管理员需要定时查询这个临时段需求,然后根据情况,不断的进行调整,做好数据排序查询优化功能。51Testing软件测试网"l)upUBL9Z&|*E

51Testing软件测试网$I'BwO"z T0?@4Dm.q/H?

  而在微软的SQL Server数据库中,笔者没有发现类似的功能。51Testing软件测试网0S m y6d {6XC6{_

51Testing软件测试网#qIe?.LOY }g ~

  二、利用哈希联接,提高多表查询性能。51Testing软件测试网I!C3dIq'b K

51Testing软件测试网uJlh }8@K.[

   多表之间的关联查询,无论是哪种关联类型,到数据量比较大时,对于数据库服务器的查询性能都是一个非常大的考验。所以,在实际数据库设计中,当数据量比 较大的时候,需要采用哈希联接,来提高数据库多表查询的效率。一般来说,哈希联接比其他几种表之间的连接方式,对于服务器来说开销要小得多,从而可以提高 服务器的查询效率。51Testing软件测试网]#O&L.@3V

6?%Y!q0S~].GU0  哈希联接一共有三种联接方式,分别为内存中的哈希联结、Gracle哈希联接与递归哈希联接。51Testing软件测试网ut#H\ ~7r%G

GB_@+i0  所 谓内存的哈希联接,是指先扫描或计算整个生成输入,然后在内存中生成哈希表。根据哈希键计算出哈希值,然后将每行插入哈希存储。如果整个生成输入比可用内 存少,则可以将所有行都插入到哈希表中。生成阶段之后就是探测阶段。一次一行的3对整个探测输入进行扫描或者计算,并为每个探测行计算哈希健的值,并按一 定的规则生成匹配项。51Testing软件测试网 N7?)Y.v#t.a"`f7L

YnAKe Rku+@'O0  其他两种哈希联接也各有各的用途,在这里就不重复描述了。下面,笔者谈谈在这两个数据库中,对于哈希联接所持的不同态度。51Testing软件测试网8X0KU(f7@o4T

6A8L:r? d2R dB V0  在微软的SQL Server数据库中,默认情况下,是采用哈希联接的。在优化过程中并不能够确定到底采用上面的那种联接方式。所以,微软的数据库系统默认情况下,实采用内存中的哈希联接,然后再根据生成输入的大小逐渐转换到GRACLE哈希联接以及递归哈希联接。51Testing软件测试网;tp$Y m F2h'xRV

j2E6x%`#S3{l v0   但是,若是在数据量不大的情况下,哈希联接不但不会提高数据库的查询效率,反而会有所下降。所以,Oracle数据库在默认情况下,是没有启用哈希联接 的,而是在实际需要时,可添加一些设置使得数据库在有多大联接查询发生时才利用哈希联结。也就是说,Oracle数据库可以设置判断条件,数据库管理员可 以指定,当满足一定的条件时才调用哈希联结,利用它来提高多表查询的效率。51Testing软件测试网8H,PL b5Q LIU(t

51Testing软件测试网5~A&HE+h1x a

三、大表查询优化。51Testing软件测试网*k4dg8z?2v][ k

x$X6a1Y:^#q*j0  一般来说,在数据库设计中,数据库设计人员会利用索引等技术来提高数据库的查询效率。但是,索引的作用,也不是无限扩大的,它受到一定的限制。 一般来说,他跟数据量是成反比的,当数据量越大时,他的作用就越小。确切的说,刚开始时随着数据量的增大其对数据库查询的优化作用会逐渐增大;但是,当数 据数量累积到一定程度时,其效果就会逐渐减小。当数据量达到一定的程度,如一百万条时,索引的作用就非常微小了。

kyT$Q"e%m.WN0

Qym\m`0  针对这种大容量记录的表,若需要查询,其查询效率不高。为此,数据库该采用什么方式来提高这个大表的查询效率呢?51Testing软件测试网 l'i'T4[ g3Z

51Testing软件测试网d U!V5c3k ~f)s

  这两大数据库不约而同的采用了哈希族的方式,来提高大表的查询。

OSn*R6zK],r7x0

oQlD[Xx.V8m/UE0  如现在在设计一个图书馆管理系统,这个系统中,读者的信息有几百万、几千万条。当读者的信息存储在一个普通表中的时候,这些记录按照存储到数据 库中的先后顺序,物理地保存到分配的块中。也就是说,数据库服务器的数据文件,或者数据表,就好像一个个抽屉,数据库是按先后顺序一条记录一条记录地从上 到下存放数据。当整个表的容量逐渐增加时,该表相应的速度就会非常慢。51Testing软件测试网'U s8H-_Eao

51Testing软件测试网!U+D6s Vcf4D

  在刚开始的时候,人们想到了利用镞表的方式来提高这个性能。也就是说,把整个抽屉分成几排,然后每排给他们归一类,如按办图书卡时的年龄进行分 类,10岁以下的一类,10岁到15岁的一类等等。如此的话,在存读者信息的时候,就不会简单的按照办卡时间来存储,而是按照类别来存储。如果是属于10 岁到15岁整个类,就会被物理的存储在同一个系列的块中。如此的话,就可以分类查找信息的速度。如果可以按类别查找数据信息,速度会非常快。51Testing软件测试网P.C%|.Ma/lSOG/bMV

1]Dp*P,lF"{0  但是,随着数据库中的镞块增加,会影响数据库的整体运行性能。这个问题发生之后,数据库开发人员又想到了利用哈希函数来解决这个问题。哈希函数将会给定一个数值用来限定镞块数的数量的预计范围。

o$p{#e!@@)I|]];^+G0

I'd(~Fi3OH*v0  也就是说,现在我们要建立一个图书馆用户的表格,我们可以利用图书卡的卡号作为镞主键将有利于数据的存储分布。但是,当读者增加时,就需要使用一个哈希函数来约束镞块的数量。

~tE#uc*Ipl6h |n0

}l[Z-v `0  不过Oracle数据库在使用镞技术来优化大表数据查询之外,还采用了另外一种独有的技术,即分区表的形式,来提高用户对于大表的查询效率。

0? Me!dagJ0

[4_kVf8@,h*b0  在Oracle数据库中,可以将一个大表分开放置在几个逻辑分区中,或者是将一个大表分成几张小表。在查询时,即可以单独的对这些小表进行查询,而且,也可以利用union all参数进行一起查询。

s yv"DS1y&t@ L1k0

y-`&hp h$\ L$z1o1PP0  如在设计销售订单管理系统时,我们可以按年度把销售订单表分割成几张小表,如此的话,后续的查询效率会比一张大表高很多。不过,这个技术的应 用,关键在于如何对表进行分割,以及如何把表放置在几个逻辑分区中,这需要有一定经验的数据库设计工程师才能设计出一个好的方案。关于这方面的内容,在后 续的文章中,笔者会有所阐述。

s5^!a-Vy,Z,Gg8W~051Testing软件测试网8gU$n5\oS

  四、在SQL语句上的查询优化。

@!E?1` OX051Testing软件测试网-D}g)d`8?S6j1A

  前台的应用程序要在数据库服务器上起作用,最终靠的都是应用程序中的一条条SQL语句。据不完全统 计,SQL语句消耗了数据库服务器80%左右的资源。所以,如何提高SQL语句的执行效率,是在数据库查询 优化中必须要考虑的一个问题。

^.{3z0XX6@0

(x0bHZ)T1yG:A/|0  但是,在实际工作中,许多程序员有个误区,他们认为数据库查询优化不是他们的事情,而应该是数 据库管理系统的任务,这是很多程序员的一个错误认识。他们错误地认为,他们所开发的应用程序的性能 ,跟他们所编写的SQL语句关系不大。一个好的查询语句往往可以使得应用程序的性能提高数十倍,而且 ,随着记录量的增加,这个效果还会以几何级数上升。51Testing软件测试网Jv*b/R N:mv9@i

51Testing软件测试网UL"q,Q Q_"|'ud

  另外,SQL语句是独立于程序设计逻辑的,也就是说,无论你的业务逻辑是怎么设计的,最后分解成 SQL语句,就是那么几个语法,所以,相对于应用程序源代码的优化,SQL查询语句的优化在时间与风险上 ,都要低许多。

d2b,\yuI0

)}'S]:H`.^H4Gu.NV0  对于SQL语句的优化,Oracle数据库与SQL Server数据库有类似的地方,也有一些差异。下面笔者就这 两者的差异与共同点做一个综合介绍。

fOpt b0

8d{S-zr"h;x0  1、通过索引来提高SQL语句的执行效率。

`"z*VX4N xo051Testing软件测试网EB F,\KV2ns

  一般来说,对于一些经常需要查询的表,如产品信息表,我们可以通过建立外键来提高查询效率。但 是,也不是说每个字段都要指定为外键。对于一些没有指定外键的字段,我们可以为其建立索引,来提高 数据表的查询效率。51Testing软件测试网9?f j ZN rd)]H'J2]s

51Testing软件测试网1Gd p1U|QB-F*EMJ

  一般情况,在以下几种情况下,我们可以为表建立索引来提高SQL语句的执行效率。

|"UH}%s$~t%\pu0

0kwE+x(L0  一是对于一些经常需要查询的表,我们出于某种考虑,没有设置外键,而是通过设置索引来提高对于 表的查询效率。在数据库表中,外键的设置往往受到一些限制;而相对于外键来说,索引的限制则要小得 多。所以,在一些不使用外键的情况下,我们可以采用索引来提高对于表的查询效率。

I:ik+ulalm+Z Tp0

*]C/Yzo9\y^f0二是在需要频繁进行排序或者分组的表上,建立索引,可以极大地提高查询效率。如ERP系统在设计的 时候,可能需要频繁地查询采购订单明细,而且,这份报表是需要根据采购订单的号码进行排序。如此的 话,在数据库设计的时候,就可以把采购订单的号码设置为索引,在每次运行采购订单明细作业的时候, 前台ERP程序的性能就会高许多。而有时候,可能需要按供应商来统计当天的进货金额,此时,最好能够 在进货明细表中,给供应商字段添加索引,这对于提高当天进货汇总表作业的运行效率,会有非常大的帮 助。总之,在分组查询或者排序查询的表上,设置索引对于提高应用程序的整体性能,具有不可忽视的作 用。

o)fcm8CS?D*}0

e;Tf"|4I0  三是如果待排序的列有多个,则需要在这些列上建立复合索引。如前台应用程序在生成当天的进货明 细表时,需要按供应商、采购订单号、产品编号进行排序。此时,也就是说,在生成进货明细表这份报表 时,要按这三个字段进行排序。遇到这种情况时,对这些字段建立复合索引,提高查询效率,是一个不错 的选择。

nGR`^+^U6w0

Jo U#vf+]0  以上这些SQL语句优化,Oracle数据库与SQL Server数据库都可以实现。虽然具体的实现语句可能稍有 区别,但都是换汤不换药,没有本质区别。51Testing软件测试网9k(qcA)w!tf

51Testing软件测试网C:g$W8V8D4j2eIF

  2、把索引与数据文件存放在不同的磁盘中。

rL7uR.c051Testing软件测试网5Fb qges

  当索引或者数据库文件比较庞大时,把他们放在同一个磁盘中会加大输入输出等竞争,从而抵消了索 引的作用。为了解决过多的索引导致输入输出效率降低的问题,在数据库设计的时候,最好把索引跟用户 的表空间建立在不同的磁盘中。如把数据库的表空间建立在一块硬盘中,而把索引建立在另外一块硬盘中 。如此的话,就可以明显地降低输入输出竞争。也就是说,这样设计,随着索引的增加,不会导致输入输 出效率的低下。

`!N'i6Q%`2c(N6\B051Testing软件测试网qHs*b[

  不过,根据笔者的了解,索引与数据文件存放在不同的磁盘中,现在好像只有Oracle 数据库可以做到 ,而微软的SQL Server数据库则无法实现这一点。

d l4kxc+y&G:R _0

*F;p4{%s-\H `z[ n0  这也许根他们的定位不同。甲骨文的数据库系统是针对大型的数据库应用而设计,所以,对于查询的 效率要求更加高。

4_#}qj3o0

SUv7T!Z5Z r0  3、合理利用群集索引来提高SQL语句的执行效率。51Testing软件测试网u@%h1rD}0J

"l x6QI"zo^WA0  在一些特殊情况下,我们需要用到群集索引。如在ERP系统中,采购部门经常需要按月来查询采购订单 明细。如需要查询2008年8月份的采购订单明细,而且这份报表需要按照供应商、采购订单号码、产品品 号、交货期等进行排序,有时候还需要对供应商进行汇总。这一份简单的报表,用到了范围查询、多个字 段记录排序、记录汇总等技术。此时,若能够建立群集索引的话,对于提高这份报表的查询效率,具有非 常明显的效果,特别是在数据记录比较多的情况下,效果特别明显。51Testing软件测试网 I"r6T2[1zf+F3m&`2s

)u|'HW"P0  所谓的群集索引与非群集索引的区别,主要是在于数据存放记录上的差异。若我们采用群集索引的话 ,在存放记录的时候,会按群集索引指定的规则存放。如对于采购订单中的供应商ID字段采用群集索引, 则在存放记录的时候,会把相同的供应商存放在一起。如此的话,在查询的时候,效率就会高得多。而若 没有采用群集索引的话,则记录保存时就是按记录保存的先后顺序来进行记录的存储。51Testing软件测试网vP;F.p@[

51Testing软件测试网9r v4`/|3W$BSQ

  在建立群集索引的时候,Oracle 数据库有一个,就是必须在数据库表建立的时候,数据还没导入之前 就建立群集索引。也就是说,若数据库表中有记录的话,则无法建立群集索引,这一点我们需要引起注意 。

ooB_j%{`-S@0

/i]AH ^,?"zwh T0  同时,若给某个表中的字段建立了群集索引,在记录保存时,为了能够按照群集索引所指定的规则存 储数据,需要对数据表中的记录进行一些调整,以符合原有的规则,如此的话,就会让数据库进行一些额 外的动作,从而影响数据库的性能。如在建立某个供应商的采购记录时,为了把相同供应商的记录保存在 一起(如我们把供应商ID设置为群集索引),就需要调整原有的记录存储结构。虽然在保存的时候,牺牲一 点效率,但是,这对于后续数据查询,效率就会高许多。所以,对于群集索引的话,要让其取得比较高的 效果,有一个应用前提,就是这个表中的数据要是经常查询的。如在ERP系统中,有一个库存历史交易报 表,这个查询就会经常用到,而且,在查询的过程中,都需要用到范围查询、排序、汇总等功能。所以, 用在库存历史交易等数据库表中,则效果会好得多。

j@b]|s#evEJ051Testing软件测试网Sm/f;xXi]z

  若利用一句话来区分群集索引与非群集索引的区别,那就是群集索引“更新慢,查询难快”。51Testing软件测试网,z c:].UK y5C

51Testing软件测试网&v#m]Kv

  在实际应用中,如果利用SQL Server设计数据库系统的过程中,很少用到群集索引技术(根据笔者的了 解)。而在Oracle数据库系统中,则应用的相对比较广泛一点。

B@T.j2H m y1LV0

r*`#[8k F ?/el0  不过,两个数据库在群集索引上都有一个共同点,就是要利用索引的话,必须在数据表建立的时候, 就要设置群集索引。当数据库中有记录的话,是不能建立群集索引的。

x_Axj^051Testing软件测试网_!w~T%GW(aQ

  说起区别,具体的实现语法有点差异,但是没有什么本质的区别。另外,对于甲骨文的数据库来说, 可以把群集索引跟数据库文件存放在不同的磁盘中,从而提高输入输出效率。但是,微软的SQL Server数 据库则不行。51Testing软件测试网/v!O3CW0C2`EB

K,M]@qs0  4、使用Oracle数据库自带的优化器优化SQL语句。

Y7}'U8^^'}-r'EN0

F ?^"t&m0  在Oracle数据库中,自带了一个SQL语句的优化工具,Oracle语句优化器。利用这个工具,可以提高 SQL语句的执行效率。

k5Zu&nj,R$v3xtW0i.b6p0

^&MQF6t,`0  一方面,Oracle数据库语句优化器是跟行锁管理工具一起使用的,两者往往需要配合使用,才能够起 到意想不到的作用。另一方面,对于“扶不起的阿斗”,Oracle语句优化器也无能为力。也就是说,对于 一些实在写得很糟糕的SQL语句,语句优化器对其也没有丝毫办法;只有对一些本来就比较合理的SQL语句 ,语句优化器与行锁管理工具,才能够在这个基础之上,再找到一些可以改善的地方,然后提出可行的改 善意见。

+aL@)f/q8m^*}0

nG \ TvZ0  具体来说,语句优化器,一方面确定SQL语句的最小代价执行计划,同时,确定数据的访问路径,如是 否采用索引或者表扫描;采用合理的表连接方式以及顺序;判断索引不可使用时是否需要进行排序等等。综 合以上因素,然后给我们提出一个改善的建议。

!j8Osy L"g051Testing软件测试网K@;xZi!N

  在实际工作中,语句优化器可以给我们找出一个SQL语句优化过程中的盲点。而这个工具是微软SQL Server数据库所缺乏的,或者跟甲骨文的数据库比起来,有差距的地方。

1E,Zx1sv~|#qx^0

TAG:

 

评分:0

我来说两句

Open Toolbar