Orace 优化sql查询

    在使用SQL往往会陷入一个区,即太注于所得的果是否正确,而忽略了不同的实现方法之可能存在的性能差异,这种性能差异在大型的或是复杂的数据库环境中(如机事务处OLTP或决策支持系DSS)中表得尤

    笔者在工作 践中 发现 ,不良的 SQL 往往来自于不恰当的索引 设计 、不充份的 接条件和不可 化的 where 子句。
   在 们进 行适当的 化后,其运行速度有了明 地提高!
   下面我将从 三个方面分 别进 总结
一、不合理的索引设计----
例:表 record 620000 行, 看在不同的索引下,下面几个  SQL 的运行情况:
---- 1. date 上建有一非个群集索引
select count(*) from record where date >'19991201' and date < '19991214'and amount >2000 (25)
select date ,sum(amount) from record group by date(55)
select count(*) from record where date >'19990901' and place in ('BJ','SH') (27)
----  分析: ----
date 上有大量的重 复值 ,在非群集索引下,数据在物理上随机存放在数据 上,在范 围查 ,必 须执 行一次表 描才能找到 一范 内的全部行。
---- 2. date 上的一个群集索引
select count(*) from record where date >'19991201' and date < '19991214' and amount >2000 14秒)
select date,sum(amount) from record group by date28秒)
select count(*) from record where date >'19990901' and place in ('BJ','SH')14秒)
----  分析: ----  在群集索引下,数据在物理上按 序在数据 上,重 复值 也排列在一起,因而在范 围查 ,可以先找到 个范 的起末点,且只在 个范 描数据 ,避免了大范 围扫 描,提高了 查询 速度。
---- 3. place date amount 上的 合索引
select count(*) from record where date >'19991201' and date < '19991214' and amount >2000 26秒)
select date,sum(amount) from record group by date27秒)
select count(*) from record where date >'19990901' and place in ('BJ, 'SH')< 1秒)
----  分析: ----  是一个不很合理的 合索引,因 它的前 列是 place ,第一和第二条 SQL 没有引用 place ,因此也没有利用上索引;第三个 SQL 使用了 place ,且引用的所有列都包含在 合索引中,形成了索引覆盖,所以它的速度是非常快的。
---- 4. date place amount 上的 合索引
select count(*) from record where date >'19991201' and date < '19991214' and amount >2000(< 1)
select date,sum(amount) from record group by date11秒)
select count(*) from record where date >'19990901' and place in ('BJ','SH')< 1秒)
----  分析: ----  是一个合理的 合索引。它将 date 列,使 SQL 都可以利用索引,并且在第一和第三个 SQL 中形成了索引覆盖,因而性能达到了最
---- 5. 总结 ----
缺省情况下建立的索引是非群集索引,但有 它并不是最佳的;合理的索引 设计 要建立在 种查询 的分析和 预测 上。
一般来
. 有大量重 复值 、且 常有范 围查询 between, >,<  >=,< = )和 order by group by 生的列,可考 建立群集索引;
. 常同 存取多列,且 列都含有重 复值 可考 建立 合索引;
. 合索引要尽量使 关键查询 形成索引覆盖,其前 列一定是使用最 繁的列。
 
二、不充份的接条件:
例:表 card 7896 行,在 card_no 上有一个非聚集索引,表 account 191122 行,在 account_no 上有一个非聚集索引, 看在不同的表 接条件下,两个 SQL 行情况:
select sum(a.amount) from account a,card b where a.card_no = b.card_no20秒)
select sum(a.amount) from account a,card b where a.card_no = b.card_no and a.account_no=b.account_no< 1秒)
----  分析: ----  在第一个 接条件下,最佳 查询 方案是将 account 作外 表, card 作内 表,利用 card 上的索引,其 I/O 次数可由以下公式估算
account 上的 22541 + (外 account 191122 * card 对应 表第一行所要 找的 3 =595907 I/O
在第二个 接条件下,最佳 查询 方案是将 card 作外 表, account 作内 表,利用 account 上的索引,其 I/O 次数可由以下公式估算 :外 card 上的 1944 + (外 card 7896 * account 对应 一行所要 找的 4 = 33528 I/O
,只有充份的 接条件,真正的最佳方案才会被 行。
总结
   1. 多表操作在被 实际执 行前, 查询优 化器会根据 接条件,列出几 可能的 接方案并从中找出系 统开销 最小的最佳方案。 接条件要充份考 虑带 有索引的表、行数多的表;内外表的 选择 可由公式:外 表中的匹配行数 * 表中 一次 找的次数确定,乘 最小 最佳方案。
   2. 行方案的方法 --  set showplan on ,打 showplan 选项 ,就可以看到 序、使用何 索引的信息;想看更 详细 的信息,需用 sa 角色 dbcc(3604,310,302)

你可能感兴趣的:(sql)