个人的总结:
段和数据文件是多对多关系。
一个段不能跨多个表空间,
一个区不能在多个数据文件上的。
粒度由大到小一次:表空间、数据文件、段、区、块。
问题:
一个表的一行占用多少空间,一个表由占用多少空间?
为什么有的表不大,但是查询起来也很慢的呢?
当然,这是可以从视图中看出来,但是呢,了解oracle的底层结构,对一些调优的东西应该是大有裨益的。
一个测试:
SQL> set timing on
SQL> set autotrace on
SQL> select sysdate from dual
2 /
SYSDATE
--------------
07-12月-10
已用时间: 00: 00: 00.00
执行计划
----------------------------------------------------------
Plan hash value: 1388734953
-----------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |
| 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
412 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
①写入500 0000条数据
SQL>
2
3 BEGIN
4 FOR I IN 1..5000000 LOOP
5 INSERT INTO td_test VALUES(I);
6 END LOOP;
7 commit;
8 END ;
9 /
PL/SQL 过程已成功完成。
已用时间: 00: 03: 32.17
②SQL> SELECT COUNT(*)
2 FROM TD_TEST
3 /
FROM TD_TEST
*
第 2 行出现错误:
ORA-00376: 此时无法读取文件 4
ORA-01110: 数据文件 4: 'F:\ORACLE\RURU\RURU\USERS01.DBF'
note:
为什么会出错哪?因为此刻修改表空间为offline状态。
SQL> alter tablespace users offline
2 /
Tablespace altered
SQL> alter tablespace users oNline
2 /
Tablespace altered
SQL> SELECT COUNT(*)
2 FROM TD_TEST
3 /
COUNT(*)
----------
5000000
已用时间: 00: 00: 27.78
执行计划
----------------------------------------------------------
Plan hash value: 1193277808
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 16324 (2)| 00:03:16 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TD_TEST | 5242K| 16324 (2)| 00:03:16 |
----------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
统计信息
----------------------------------------------------------
1 recursive calls
1 db block gets
147460 consistent gets
73973 physical reads
5298124 redo size
408 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL>
2
3 BEGIN
4 FOR I IN 5000000..9000000 LOOP
5 INSERT INTO td_test VALUES(I);
6 END LOOP;
7 COMMIT;
8 END ;
9 /
PL/SQL 过程已成功完成。
已用时间: 00: 03: 32.62
SQL> select count(*)
2 from td_test
3 /
COUNT(*)
----------
9000001
已用时间: 00: 00: 23.78
执行计划
----------------------------------------------------------
Plan hash value: 1193277808
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 29564 (2)| 00:05:55 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TD_TEST | 9637K| 29564 (2)| 00:05:55 |
----------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
统计信息
----------------------------------------------------------
6 recursive calls
1 db block gets
191556 consistent gets
111996 physical reads
4234540 redo size
411 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
③SQL> delete td_test;
已删除9000001行。
已用时间: 00: 07: 45.82
执行计划
----------------------------------------------------------
Plan hash value: 3749660188
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 1 | 29316 (1)| 00:05:52 |
| 1 | DELETE | TD_TEST | | | |
| 2 | TABLE ACCESS FULL| TD_TEST | 1 | 29316 (1)| 00:05:52 |
----------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
统计信息
----------------------------------------------------------
24892 recursive calls
10031653 db block gets
183347 consistent gets
132412 physical reads
3030303220 redo size
680 bytes sent via SQL*Net to client
550 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
9000001 rows processed
SQL> commit;
提交完成。
已用时间: 00: 00: 00.00
④delete后继续执行同样的语句
SQL> select count(*)
2 from td_test
3 /
COUNT(*)
----------
0
已用时间: 00: 01: 00.84
执行计划
----------------------------------------------------------
Plan hash value: 1193277808
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 29316 (1)| 00:05:52 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TD_TEST | 1 | 29316 (1)| 00:05:52 |
----------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
264874 consistent gets
106352 physical reads
9547808 redo size
407 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
⑤truncate 后执行同样的语句
SQL> truncate table td_test
2 /
表被截断。
已用时间: 00: 00: 03.96
SQL> select count(*)
2 from td_test
3 /
COUNT(*)
----------
0
已用时间: 00: 00: 00.00
执行计划
----------------------------------------------------------
Plan hash value: 1193277808
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TD_TEST | 1 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
统计信息
----------------------------------------------------------
1 recursive calls
1 db block gets
6 consistent gets
0 physical reads
96 redo size
407 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
总结:
1、不能简单的看执行计划,而应该看表对应的段里到底有多少个块,块是oracle读写输入输出的基本单位哦,因此会出现一个表中没有数据,但是也会查半天的情况。
2、delete和truncate之后读的块为甚麽相差那么多?也就是delete之后表对应的段中所包含的块并没有减少,而truncate却少了。
3、后面的统计信息还是很有用的,
6 consistentgets 逻辑读
0 physical reads 物理读
4、优化的原则是尽可能的少读少写。少读就是少扫描block。