代码改变世界

优化利器In-Memory开启和效果

2023-03-18 23:46  AlfredZhao  阅读(211)  评论(0编辑  收藏  举报

本文主要介绍Oracle In-Memory 选件,Oracle在12.1.0.2就已经推出了In-Memory这个选件,现在通常会建议所有使用19.8及之后版本的用户,有条件都要留给In-memory一点内存区域。
因为该选件在19.8之后推出了16GB及以下免费使用的福利,作为优化的又一利器。

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+)来举例说明。

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

select count(*) from L;

vi select2.sql

select /*+ no_inmemory */ count(*) from L;

vi xplan.sql

set lines 200 pages 200
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

下面测试中开启计时。
执行前面已执行过的语句(确保都在内存区域中),然后对比二者性能差异,并查看执行计划确认;

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的性能差异。
抛砖引玉,感兴趣的话快在自己的测试环境试试效果吧!