本文主要介绍Oracle In-Memory 选件,Oracle在12.1.0.2就已经推出了In-Memory这个选件,现在通常会建议所有使用19.8及之后版本的用户,有条件都要留给In-memory一点内存区域。 因为该选件在19.8之后推出了16GB及以下免费使用的福利,作为优化的又一利器。
- 1.如何开启
- 2.测试效果
1.如何开启
只需要最简单的inmemory_size
参数设置。
如果是第一次设置这个参数,需要重启生效。我这里测试环境,假设设置8GB的In-Memory:
SQL> alter system set inmemory_size=8G scope=spfile;
System altered.
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>
SQL> startup
ORACLE instance started.
Total System Global Area 2.5367E 10 bytes
Fixed Size 18608792 bytes
Variable Size 2248146944 bytes
Database Buffers 1.4496E 10 bytes
Redo Buffers 14942208 bytes
In-Memory Area 8589934592 bytes <--- 这里重新启动实例后,可以看到In-Memory的内存区域已经按照我们的设置开辟。
Database mounted.
Database opened.
SQL> show parameter inmemory_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
inmemory_size big integer 8G
2.测试效果
以一张我测试环境中的一张大表L(数据量50M,占空间5G )来举例说明。
代码语言:javascript复制SQL> select round(bytes/1024/1024/1024,2) "GB" from user_segments where segment_name = 'L';
GB
----------
5.38
--将该表设置为inmemory:
SQL> alter table L inmemory;
--如果最终想去掉该表的inmemory设置,即设置为no inmemory:
SQL> alter table L no inmemory;
使用最简单的测试SQL用例:
vi select.sql
代码语言:javascript复制select count(*) from L;
vi select2.sql
代码语言:javascript复制select /* no_inmemory */ count(*) from L;
vi xplan.sql
代码语言:javascript复制set lines 200 pages 200
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
下面测试中开启计时。 执行前面已执行过的语句(确保都在内存区域中),然后对比二者性能差异,并查看执行计划确认;
代码语言:javascript复制SQL> set timing on
SQL> @select
COUNT(*)
----------
53986608
Elapsed: 00:00:00.02 <---瞬间出结果,仅需0.02s!
SQL> @xplan
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 38aj72xpvgqfv, child number 1
-------------------------------------
select count(*) from L
Plan hash value: 1622156267
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.02 | 13 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.02 | 13 |
| 2 | TABLE ACCESS INMEMORY FULL| L | 1 | 53M| 53M|00:00:00.02 | 13 | <--- 这里唯一区别是有`INMEMORY`关键字。
----------------------------------------------------------------------------------------------
14 rows selected.
Elapsed: 00:00:00.03
SQL> @select2
COUNT(*)
----------
53986608
Elapsed: 00:00:02.22 <---即便多次反复查询,也都至少需要2s以上才能出结果。
SQL> @xplan
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 2t6ccax38rrgt, child number 0
-------------------------------------
select /* no_inmemory */ count(*) from L
Plan hash value: 1622156267 <--- 注意这里的Plan hash value和上面是一致的。
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:02.23 | 697K| 697K|
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:02.23 | 697K| 697K|
| 2 | TABLE ACCESS FULL| L | 1 | 53M| 53M|00:00:02.18 | 697K| 697K| <--- 只是这里没有了`INMEMORY`关键字。
----------------------------------------------------------------------------------------------
14 rows selected.
Elapsed: 00:00:00.03
SQL>
上面简单对比了同样在内存中,计算count(*)这类统计操作,普通buffer cache与In-Memory的性能差异。 抛砖引玉,感兴趣的话快在自己的测试环境试试效果吧!