`
ganqing1234
  • 浏览: 168565 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

《Oracle SQL高级编程 》笔记

 
阅读更多

 

一 SQL核心

group by子句执行from和where子句后得到的经过筛选后的结果进行聚合。

select列表里面的任何非聚合字段都必须包含在group by表达式中。

group by 和 having的字句顺序可以互换,谁先谁后无关紧要。本质上说having子句是在group by执行后筛选汇总。

 

select子句问题,当使用另外一个select语句产生一列值时,这个查询必须只能返回一行一列的值(该用法叫标量子查询)。

尽量避免使用标量子查询,因为它在结果集中每一行都要执行一遍。

distinct子句,用来在其他子句执行完毕后从结果集中去除重复的行。

 

order by,oracle中order by必须在其他所有子句都执行完之后执行。需要排序的数据量大小影响性能,数据量指结果中的字节数

可以用行数乘以每一行的字节数来估算。较小的排序可以在内存中实现,大的动用临时磁盘空间。

排序是查询过程中开销相当大的一个处理步骤。

 

二 SQL执行

SGA共享池,执行过的每一句SQL在共享池里面都有解析后的内容,存储的这些语句的地方称为库高速缓存(library cache)。

Oracle所使用的系统参数也存放这里,叫数据字典高速缓存(dictionary cache)。

最高效使用共享池,语句需要共享,如果每个sql是唯一的,就无法共享。

硬解析和软解析。

相同sql需要严格一致,大小写,有注释没有注释,参数等等。可以通过select × from v$sql查询。

SGA缓冲区缓存,在数据库块从硬盘读取出来后或者写入硬盘之前,用于存放数据库块。从缓冲区读数据块叫逻辑读取,必须从硬盘读取则称为物理读取。

查询转换,查询转换器可能为优化修改查询语句。可以使用NO_QUERY_TRANSFOERMATION提示禁止。

 

三 联结方法

查询多张表,优化器决定怎么连接效率最高。分为:嵌套循环联结、散列联结、排序-合并联结、笛卡尔联结。

每个联结方法分为两个分支:访问的第一张表叫驱动表,第二张表叫内层表或者被驱动表。优化器来确定哪张表作为驱动表。

预估大小最小(就块、数据行及字节)的表通常作为驱动表。

嵌套循环联结:外层循环就是一个只使用where子句中的属于驱动表的条件对它进行的查询。然后获取的行就会逐个进入到内层循环中。

如果内层循环检查也匹配,就会传递到查询计划的下一步(如果没有更多步骤就直接放入最终结果集中)。

嵌套循环联结优点是内存使用非常少,因为数据行集一次只加工一行,但是大数据集处理时间较长。

排序-合并联结:先排序后合并,排序的开销非常大。适用于where条件是非等式的查询如where column1 between t2.column2 and t2.column1

散列联结:只用于相等联结。

 

四 SQL执行计划

举例:在命令窗口执行,这些只是预期的执行计划,不实际执行查询。

>explain plan for select * from esb_capability_interface;

>select * from table(dbms_xplan.display);

可以查看:

PLAN_TABLE_OUTPUT

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

Plan hash value: 2910271166

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

| Id  | Operation         | Name                     | Rows  | Bytes | Cost (%CP

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

|   0 | SELECT STATEMENT  |                          |    93 |  4557 |     3   (

|   1 |  TABLE ACCESS FULL| ESB_CAPABILITY_INTERFACE |    93 |  4557 |     3   (

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

输出包括:1.sql引用的每一张表

          2.访问每张表的方法

 3.每一对需要联结的数据源所用的联结方法

 4.按次序列出的所有需要完成的运算

 5.计划中个步骤的谓语信息列表

 6.对于每个运算,估计出改步骤所需要的操作的数据行数和字节数

 7.每个运算,计算出成本值

 8.如果适用,所访问的分区信息

 9.如果适用,并行执行的相关信息

 

五 索引

典型的基于索引的访问路径通常包含3步:

(1)遍历索引树并将SQL语句中的谓语应用到索引列后收集叶子块的行编号

(2)使用行编号从数据库块中获取数据行

(3)在所获取的数据行上应用其余的谓语来得出最终结果

索引列的选择:

(1)如果sql访问某一列上面使用了等式或者范围谓语

等等

IS NULL谓语不能使用单列索引。通过使用另一个虚拟列来创建多列索引,就可以在IS NULL子句中启用索引。

如select × from t1 where n1 is null,如果create index t1_n1 on t1(n1)单列索引,查询将全表扫描。

这时create index t1_n1 on t1(n1,0) 加入一个虚拟0值,查询时优化器会使用索引。

索引结构类型:

B-树索引 倒置的树形结构,查询索引时会遍历树。树结构过高影响性能。

位图索引 使用位图表示列值的行编号。不适用有大量更新的列或者具有较多DML操作( 数据操纵语言insert、update、delete,大量DML操作容易引起锁定问题)的表。

         适用于大多数对具有较少唯一值的列进行只读运算的数据仓库表。如要表需要定期更新,需要先删除位图索引,加载数据后在创建位图索引。

索引组织表(index organized tables, IOTs) 表本身被组织成一个索引,所有列存储在索引树自身上。常规表中每一行都有一个行编号,而在IOTs中数据行存储

在索引结构中,没有物理行编号。适用于(1)数据行长度较短的表 (2)大多使用主键进行访问的表

可以通过organization index建立IOT Sales_iot,IOT是一种能够有效减少数据行而且需要进行大量DML和Select活动的表中额外索引特殊结构。

 

索引分区

局部索引:局部分区索引使用local关键字来建立,分区边界与表相同。与每个表分区相联结的有一个索引分区。因为维护操作可以在独立分区进行,表的可用性更好,

对于索引分区的维护仅需要锁定相应的表分区而不是整张表。分区数过多(几千)影响性能。

全局索引:用GLOBAL来创建。索引的分区边界和表的分区边界不一定要匹配,表和索引分区键也可以不一样。

散列分区和范围分区

 

如果一个谓语在索引列上应用了函数,优化器不会选用该列上的索引。如to_char(id)='100',就不会选用id列上的索引。

create index t1_index on t1(to_char(id))

函数必须是确定性函数,即每次执行必须返回一致的值。

 

六 Select之外内容

如果需要删除整张表或者分区内的所有数据行,使用TRUNCATE效率更高。

缺点:是DDL命令,有一次隐式提交(一旦截断就提交了,没法恢复)|只能整张表截断|不能闪回表截断之前的状态

merge 表存在就更新,否则插入。9i版本引入。

merge into table_name using (subquery) on (subquery.column=table.column)

when matched then update ...

when not matched then insert ...

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics