大小表区分按照数据量的大小区分;

通常对于小表,Oracle建议通过全表扫描进行数据访问,对于大表则应该通过索引以加快数据查询,当然如果查询要求返回表中大部分或者全部数据,那么全表扫描可能仍然是最好的选择。
从V$SYSSTAT视图中,我们可以查询得到关于全表扫描的系统统计信息:

SQL> col name for a30 
SQL> select name,value from v$sysstat
2 where name in ('table scans (short tables)','table scans (long tables)');

NAME VALUE
------------------------------ ----------
table scans (short tables) 828
table scans (long tables) 101

其中table scans (short tables)指对于小表的全表扫描的此时;table scans (long tables)指对于大表的全表扫描的次数。
从Statspack的报告中,我们也可以找到这部分信息:

Instance Activity Stats for DB: CELLSTAR Instance: ora8i Snaps: 20 -

Statistic Total per Second per Trans 
--------------------------------- ---------------- ------------ ------------ 
。。。。。。
table scan blocks gotten 38,228,349 37.0 26.9 
table scan rows gotten 546,452,583 528.9 383.8 
table scans (direct read) 5,784 0.0 0.0 
table scans (long tables) 5,990 0.0 0.0 
table scans (rowid ranges) 5,850 0.0 0.0 
table scans (short tables) 1,185,275 1.2 0.8

通常,如果一个数据库的table scans (long tables)过多,那么db file scattered read等待事件可能同样非常显著,和以上数据来自同一个report的Top5等待事件就是如此:

Top 5 Wait Events 
~~~~~~~~~~~~~~~~~ Wait % Total
Event Waits Time (cs) Wt Time
-------------------------------------------- ------------ ------------ -------
log file parallel write 1,436,993 1,102,188 10.80
log buffer space 16,698 873,203 8.56
log file sync 1,413,374 654,587 6.42
control file parallel write 329,777 510,078 5.00
db file scattered read 425,578 132,537 1.30

数据库内部,很多信息和现象都是紧密相关的,只要我们加深对于数据库的了解,在优化和诊断数据库问题时就能够得心应手。

Oracle通过一个内部参数_small_table_threshold来定义大表和小表的界限。缺省的该参数等于2%的Buffer数量,如果表的大小小于该参数定义,Oracle认为该表为小表,否则Oracle认为该表为大表。
我们看一下Oracle9iR2中的情况:

SQL> @@GetParDescrb.sql
Enter value for par: small
old 6: AND x.ksppinm LIKE '%&par%'
new 6: AND x.ksppinm LIKE '%small%'

NAME VALUE DESCRIB
------------------------------ -------------------- ------------------------------------------------------------
_small_table_threshold 200 threshold level of table size for direct reads

以上数据库中,200正好约为Buffer数量的2%:

SQL> show parameter db_cache_size

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_cache_size big integer 83886080
SQL> select (83886080/8192)*2/100 from dual;

(83886080/8192)*2/100
---------------------
204.8

所以要区分大小表(Long/Short)是因为全表扫描可能引起Buffer Cache的抖动,缺省的大表的全表扫描会被置于LRU的末端,以期尽快老化,减少Buffer的占用。从Oracle8i开始,Oracle的多缓冲池管理技术(Default/Keep/Recycle池)给了我们另外一个选择,对于不同大小、不同使用频率的数据表,从建表之初就可以指定其存储Buffer,以使得内存使用更加有效。

有时一个查询结果需要从两个或两个以上表中提取字段数据,此时需要使用多表关联查询。

1)笛卡尔积关联

create table a(
   id number(7),
   name varchar2(20));

create table b(
   id number(7),
   name varchar2(20));

insert into a(id,name) values(1,'a1');
  insert into a(id,name) values(2,'a2');
  insert into a(id,name) values(3,'a3');
  insert into b(id,name) values(1,'b1');
  insert into b(id,name) values(2,'b2');

select * from a,b;

笛卡尔积特点:
   --*代表from后面表中所有列
   --返回结果数量是各个表记录的乘积
   --结果是a每条记录与b每条记录结合形成

*2)等值连接
  参与等值条件的两个字段值,相等时才作为结果返回。
 select a.id,a.name,b.name //3.提取显示的字段
 from a,b //1.形成笛卡尔积结果
 where a.id=b.id; //2.返回id相等的记录

---使用[INNER] JOIN...ON...语法-----
 select a.id,a.name,b.name
 from a join b on(a.id=b.id);

提示:建议采用JOIN...ON语法,INNER JOIN和JOIN作用等价。内连接,等值连接是一个意思。
   
  ----使用JOIN...USING语法(了解)------
 select id,a.name,b.name
 from a join b using(id);

JOIN...USING使用注意事项:
 --关联的两个表中需要有相同的字段.(名字和类型相同)
 --关联的字段在使用时不能加别名

//查询员工名称,工资,所在部门编号,部门名称
  select e.ename,e.sal,e.deptno,d.dname
  from emp e join dept d 
     on(e.deptno=d.deptno);

3)外连接
  等值连接,需要两个表的关联字段等值才将结果返回。如果需要将某一个表记录全部返回,即使
  另一个表找不到对等字段记录,此时可以使用外连接。
  *a.左外连接

----使用LEFT OUTER JOIN...ON...语法------
  select e.ename,e.sal,e.deptno,d.dname
  from emp e left outer join dept d 
     on(e.deptno=d.deptno);
    
 A left outer join B on(...)
 以A表记录显示为主,B表记录为补充.当A表记录在B表找不到对等记录时,B以NULL方式补充。

b.右外连接
 select e.ename,e.sal,e.deptno,d.dname
  from emp e right outer join dept d 
     on(e.deptno=d.deptno);
 上面语句是以dept表显示为主,emp为补充.如果emp没有对等记录,字段值以NULL补充。

select * from a 
 right outer join b on(a.id=b.id);
等价于
select * from b 
 left outer join a on(a.id=b.id)

----在JOIN...ON之前的外连接写法--------
//(+)所在表为补充表,另一方是主表
select * from a,b
where a.id(+)=b.id; //jb为主,ja为补充

c.全外连接
   全外连接=左外连接+右外链接-(重复记录)
  select * from a 
    full outer join b on(a.id=b.id);

//查询部门编号,部门名称,部门员工人数
  select d.deptno,
         d.dname,
         count(e.ename) num
  from DEPT d left outer join EMP e 
    on(d.deptno=e.deptno)
  group by d.deptno,d.dname
  order by d.deptno;

EMPNO ENAME DEPTNO DNAME
...    ...    10   ...
NULL   NULL   40   ...
NULL   NULL   50   ...
//按部门分组统计,count(*)和count(ename)的区别
count(*) = 1 
count(ename) = 0

//查询部门在NEW YORK和CHICAGO的员工编号和员工名称
select e.empno,e.ename
from DEPT d join EMP e on(d.deptno=e.deptno)
where d.loc in ('NEW YORK','CHICAGO');

4)自连接
  关联双方的表是同一个表。

//查询员工编号,员工名,上级编号,上级名称
  select e.empno,e.ename,e.mgr,e1.ename
  from EMP e left outer join 
       EMP e1 on(e.mgr=e1.empno);
  //查询员工编号,员工名,所在部门名,上级编号,上级名称
  select e.empno,e.ename,d.dname,e.mgr,e1.ename
  from EMP e 
     left outer join EMP e1 on(e.mgr=e1.empno)
     left outer join DEPT d on(d.deptno=e.deptno);

 

Oracle的大表,小表与全表扫描的更多相关文章

  1. Oracle收集对表收集统计信息导致全表扫描直接路径读?

    direct path read深入解析 前言 最近碰到一件很奇葩的事情,因为某条SQL执行缓慢,原因是走了笛卡尔(两组大数据结果集),而且笛卡尔还是NL的一个部分,要循环31M次. 很容易发现是统计 ...

  2. 优化一个奇葩表设计上的全表扫描SQL

    之前在一个比较繁忙的系统抓到的耗时长.消耗CPU多的一条SQL,如下:SELECT * FROM Z_VISU_DATA_ALARM_LOG TWHERE TO_DATE(T.T_TIMESTR, ' ...

  3. Oracle 11g全表扫描以Direct Path Read方式执行

    在Oracle Database 11g中有一个新特性,全表扫描可以通过直接路径读的方式来执行(Direct Path Read),这是一个合理的变化,如果全表扫描的大量数据读取是偶发性的,则直接路径 ...

  4. Oracle 数据库禁止全表访问的时候direct path read /////

    一般在OLAP环境中,大表在进行全表扫描的时候一般会出现direct path read等待事件,如果在OLTP环境中,出现大量的direct path read直接路径读取,这样就有问题了.一般在O ...

  5. Hibernate中的HQL的基本常用小例子,单表查询与多表查询

    <span style="font-size:24px;color:#3366ff;">本文章实现HQL的以下功能:</span> /** * hql语法: ...

  6. MySQL的外键,修改表,基本数据类型,表级别操作,其他(条件,通配符,分页,排序,分组,联合,连表操作)

    MySQL的外键,修改表,基本数据类型,表级别操作,其他(条件,通配符,分页,排序,分组,联合,连表操作): a.创建2张表 create table userinfo(nid int not nul ...

  7. mysql连表操作是先连表还是先查询条件

    mysql连表操作是先连表还是先查询条件 一.总结 一句话总结: 连表操作时:先根据查询条件和查询字段确定驱动表,确定驱动表之后就可以开始连表操作了,然后再在缓存结果中根据查询条件找符合条件的数据 1 ...

  8. Oracle列操作引起的全表扫描

    首先是一种比较明显的情况: select * from table where column + 1 = 2 这里对column进行了列操作,加1以后,与column索引里的内容对不上,导致colum ...

  9. (转) 【oracle调优】优化全表扫---cache整张表或索引

    情景分析: 1)某查询必须要走全表扫描 2)该查询执行的频率相当高 3)对执行时间的要求也相当苛刻的话 4)数据库的IO比较吃紧 5)数据库的内存比较宽松 6)该表的大小没有大到离谱 以上情况下,可以 ...

随机推荐

  1. Bash基础——命令替换

    参考:Linux 下Shell 脚本几种基本命令替换区别 Command substitution 命令替换Command substitution https://www.jb51.net/arti ...

  2. aiops相关

    AIOPS的能力框架 AIOps平台能力体系 AIOps 常见应用场景 按照时间来分 AIOPS实施的关键技术 1.数据采集(硬件,业务指标等) 2.数据预处理(特征工程) 3.数据可视化 4.数据存 ...

  3. MyBatis3_[tp_41-42-43]-_动态sql_trim_自定义字符串截取_choose分支选择_update的set与if-trim 结合的动态更新

    笔记要点出错分析与总结 /** 笔记: * 查询的时候,如果某些条件,没带可能SQL拼装会有问题; * 1.-->给where 后面加上 1=1, 以后的条件都and XXX * 2. < ...

  4. HDU-1028-Ignatius and the Princess III(母函数)

    链接: https://vjudge.net/problem/HDU-1028 题意: "Well, it seems the first problem is too easy. I wi ...

  5. python pip获取所有已安装的第三包

    pip freeze > requirements.txt # 生成txt 文件 pip install -r requirements.txt # 别人使用时可以直接安装所有的包 [progr ...

  6. 使用unittest测试(基础一)

    #导入unittest单元测试框架 ##用例的方法前缀必须要以 test 开头的 #这是用来组织用例的 import unittest class TestDBQB(unittest.TestCase ...

  7. mongodb mongod.lock文件及oplog文件

    在mongodb的启动时,在数据目录下,会生成一个mongod.lock文件.如果在正常退出时,会清除这个mongod.lock文件,若要是异常退出,在下次启动的时候,会禁止启动,从而保留一份干净的一 ...

  8. 三十九.NoSQL概述 部署Redis服务 、 部署LNMP+Redis

    1. 搭建Redis服务器 在主机 192.168.4.50 上安装并启用 redis 服务 设置变量test,值为123 查看变量test的值   1.1 搭建redis服务器 1.1.1 安装re ...

  9. antd 表单获取参数

    wrappedComponentRef是为了把form的值赋值到自定的对象中 <OpenCityForm wrappedComponentRef={(inst)=>{this.cityFo ...

  10. spark常见错误【持续更新】

    错误1.错误: 找不到或无法加载主类 idea.scala代码 idea 导入的scala工程,编写代码后报该错误. 原因:\src\main\scala 包路径下没有将scala这个包设置成Sour ...