With Oracle Database 12.1.0.2, Oracle has released its In-Memory Database functionality. In short, Oracle In-Memory database provides transparent column-format memory access over an existing Oracle database. The normal row-format memory access is preserved for fast OLTP transactions; however, with new system parameters, that same data can be accessed from memory in column-format, drastically improving OLAP performance. Because it is transparent, there is no need to change applications to leverage this new functionality, which had previously only been exposed in engineered systems and ZFS as storage-level optimizations.

Enabling Oracle In-Memory Database

There are seven initialization parameter related to in-memory database, but the only one needed to enable the functionality is INMEMORY_SIZE. This system level, non-dynamic parameter specifies the amount of memory to be allocated to the in-memory database. As it is non-dynamic, a database restart is required to enable the feature.

SQL> STARTUP;
ORACLE instance started.

Total System Global Area 1610612736 bytes
Fixed Size                  2924928 bytes
Variable Size            1040191104 bytes
Database Buffers          553648128 bytes
Redo Buffers               13848576 bytes
Database mounted.
Database opened.
SQL> SHOW PARAMETER inmemory_size

NAME                                 TYPE        VALUE
------------------------------------ ----------- ---------------------------
inmemory_size                        big integer 0

SQL> ALTER SYSTEM SET inmemory_size=100M scope=spfile;

System altered.

SQL> SHUTDOWN IMMEDIATE;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> STARTUP;
ORACLE instance started.

Total System Global Area 1610612736 bytes
Fixed Size                  2924928 bytes
Variable Size            1040191104 bytes
Database Buffers          436207616 bytes
Redo Buffers               13848576 bytes
In-Memory Area            117440512 bytes
Database mounted.
Database opened.

Note that after enabling the parameter, a new line appears in the SGA details “In-Memory Area 117440512 bytes”. In this case, we have allocated 100M towards the in-memory database.

In-Memory Database Example

Now that the in-memory database is enabled, let’s work through an example to highlight the functionality. First, let’s create a user for this example, grant some privileges to that user and connect as that user:

SQL> CREATE USER inmem_user IDENTIFIED BY inmem_user;

User created.

SQL> GRANT connect, resource, unlimited tablespace, plustrace TO inmem_user;

Grant succeeded.

SQL> conn inmem_user/inmem_user
Connected.

Then let’s create two tables: one without the in-memory functionality and one with in-memory. Oracle provides the ability to use the in-memory column store at the column, partition, table, materialized view and tablespace level. For this example, we’ll just be using it in conjunction with the CREATE TABLE statement:

SQL> CREATE TABLE no_inmem
  2    NO INMEMORY
  3  AS
  4  SELECT * FROM all_objects;

Table created.

SQL> CREATE TABLE inmem
  2    INMEMORY
  3  AS
  4  SELECT * FROM all_objects;

Table created.

Now, let’s query against both tables and compare the results using AUTOTRACE:

SQL> SET AUTOTRACE ON
SQL> SELECT COUNT(*)
  2    FROM no_inmem
  3   WHERE object_id > 10000;

  COUNT(*)                                                                                                                                                                                              
----------                                                                                                                                                                                              
     69346                                                                                                                                                                                              

Execution Plan
----------------------------------------------------------                                                                                                                                              
Plan hash value: 2339683627                                                                                                                                                                             

-----------------------------------------------------------------------------                                                                                                                         
| Id | Operation          | Name     | Rows  | Bytes |Cost (%CPU)| Time     |                                                                                                                         
-----------------------------------------------------------------------------                                                                                                                         
|   0| SELECT STATEMENT   |          |     1 |     5 |  351   (1)| 00:00:01 |                                                                                                                         
|   1|  SORT AGGREGATE    |          |     1 |     5 |           |          |                                                                                                                         
|*  2|   TABLE ACCESS FULL| NO_INMEM | 65855 |   321K|  351   (1)| 00:00:01 |                                                                                                                         
-----------------------------------------------------------------------------                                                                                                                         

Predicate Information (identified by operation id):                                                                                                                                                     
---------------------------------------------------                                                                                                                                                     

   2 - filter("OBJECT_ID">10000)                                                                                                                                                                        

Statistics
----------------------------------------------------------                                                                                                                                              
         33  recursive calls                                                                                                                                                                            
          0  db block gets                                                                                                                                                                              
       1297  consistent gets                                                                                                                                                                            
       1255  physical reads                                                                                                                                                                             
          0  redo size                                                                                                                                                                                  
        544  bytes sent via SQL*Net to client                                                                                                                                                           
        551  bytes received via SQL*Net from client                                                                                                                                                     
          2  SQL*Net roundtrips to/from client                                                                                                                                                          
          2  sorts (memory)                                                                                                                                                                             
          0  sorts (disk)                                                                                                                                                                               
          1  rows processed                                                                                                                                                                             

SQL> SELECT COUNT(*)
  2    FROM inmem
  3   WHERE object_id > 10000;

  COUNT(*)                                                                                                                                                                                              
----------                                                                                                                                                                                              
     69346                                                                                                                                                                                              

Execution Plan
----------------------------------------------------------                                                                                                                                              
Plan hash value: 3697233323                                                                                                                                                                             

------------------------------------------------------------------------------                                                                                                                   
| Id| Operation                   | Name | Rows |Bytes |Cost (%CPU)|Time     |                                                                                                                   
------------------------------------------------------------------------------                                                                                                                   
|  0| SELECT STATEMENT            |      |     1|    5 |   14   (8)|00:00:01 |                                                                                                                   
|  1|  SORT AGGREGATE             |      |     1|    5 |           |         |                                                                                                                   
|* 2|   TABLE ACCESS INMEMORY FULL| INMEM| 65855|  321K|   14   (8)|00:00:01 |                                                                                                                   
------------------------------------------------------------------------------                                                                                                                   

Predicate Information (identified by operation id):                                                                                                                                                     
---------------------------------------------------                                                                                                                                                     

   2 - inmemory("OBJECT_ID">10000)                                                                                                                                                                      
       filter("OBJECT_ID">10000)                                                                                                                                                                        

Statistics
----------------------------------------------------------                                                                                                                                              
         61  recursive calls                                                                                                                                                                            
          0  db block gets                                                                                                                                                                              
       1329  consistent gets                                                                                                                                                                            
       1255  physical reads                                                                                                                                                                             
          0  redo size                                                                                                                                                                                  
        544  bytes sent via SQL*Net to client                                                                                                                                                           
        551  bytes received via SQL*Net from client                                                                                                                                                     
          2  SQL*Net roundtrips to/from client                                                                                                                                                          
          5  sorts (memory)                                                                                                                                                                             
          0  sorts (disk)                                                                                                                                                                               
          1  rows processed

Couple important things to note:

  • With in-memory database, the cost is much lower than without this functionality (14 versus 351). That shows that OLAP queries such as the example above will run much faster than before without any changes to the application.
  • The explain plan shows a new operation “TABLE ACCESS INMEMORY FULL” for the OLAP query.
  • The recursive calls double in the in-memory example due to the fact that the table is loaded into memory in two different ways. So use caution with in-memory database if you don’t have a high buffer cache hit percentage.

Link to script that contains the examples in this post.

 

 

 

 

 

Comment