全部博文(389)
分类: Oracle
2014-07-26 21:40:11
oracle 12C 非IN-MEMORY 的列处理
在之前的文章中我们测试了一下in-memory,对查询带来的性能提升体验.有朋友问我
是不是以后sql都不需要优化了,直接都放到in-memory中就可以了?事实上事情远没有这么简单,
DBA仍然需要对自己数据和业务要有很好的了解,才能做出适当的决定.
测试条件:
SQL> show parameter inmemory;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
inmemory_clause_default string
inmemory_force string DEFAULT
inmemory_max_populate_servers integer 2
inmemory_query string ENABLE
inmemory_size big integer 100M
inmemory_trickle_repopulate_servers_ integer 1
percent
optimizer_inmemory_aware boolean TRUE
创建一个表,并收集统计信息(顺便提一句,对于sys和system用户的对像不会使用in-memory)
SQL> create table c##frank.t1 as select * from dba_objects;
Table created.
SQL> alter table c##frank.t1 inmemory;
Table altered.
SQL> exec dbms_stats.gather_table_stats('C##FRANK','T1');
PL/SQL procedure successfully completed.
整张表放到in-memory里,除object_name之外
SQL> alter table c##frank.t1 no inmemory(object_name);
Table altered.
先统计一下count(object_name),由于列不存放在in_memory中,走正常的buffer cache。
SQL> select count(object_name) from c##frank.t1;
COUNT(OBJECT_NAME)
------------------
90980
Execution Plan
----------------------------------------------------------
Plan hash value: 3724264953
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 25 | 426 (1)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 25 | | |
| 2 | TABLE ACCESS FULL| T1 | 90980 | 2221K| 426 (1)| 00:00:01 |
---------------------------------------------------------------------------
根据object_id来查找object_name,会使用in-memory还是buffer cache呢?看测试
SQL> select count(object_name) from c##frank.t1 where object_id=10;
COUNT(OBJECT_NAME)
------------------
1
Execution Plan
----------------------------------------------------------
Plan hash value: 3724264953
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 | 426 (1)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 30 | | |
|* 2 | TABLE ACCESS FULL| T1 | 1 | 30 | 426 (1)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("OBJECT_ID"=10)
还是buffer cache。因为object_id在in-memory中存放,即使在in-memory中可以查找到
,但是并没有相应的行信息,所以无法定位到对应的行,这是行式和列式存储数据库的很
重要区别.
而count(*)之类的操作,还是会走in-memory.
SQL> select count(*) from c##frank.t1 where object_id=10;
COUNT(*)
----------
1
Execution Plan
----------------------------------------------------------
Plan hash value: 3724264953
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 17 (6)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | TABLE ACCESS INMEMORY FULL| T1 | 1 | 5 | 17 (6)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - inmemory("OBJECT_ID"=10)
filter("OBJECT_ID"=10)
在12C的in-memory中,对像如果使用了in-memory.数据是存放了双份的,一份是存放在in-memory中,
一份是存放在传统的buffer cache中,这两种存放的数据并没有一定的关联性.比如在in-memory中可以查到某列数据
但是其并没有对应的rowid之类的信息去指向具体的行,所以两份数据没有关联性。只有优化器去
决定使用哪种数据可以满足查询要求.