> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> This engine allows integrating ClickHouse with RocksDB

# EmbeddedRocksDB table engine

export const CloudNotSupportedBadge = () => {
  return <div className="cloudNotSupportedBadge">
            <div className="cloudNotSupportedIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.5" d="M6.33366 12.6666L12.3739 12.6667C13.6593 12.6667 14.7073 11.6187 14.7073 10.3334C14.7073 9.04804 13.6593 8.00003 12.3739 8.00003C12.3739 8.00003 12.3337 7.66659 12.0003 7.33325M10.667 5.33322C8.00033 2.33325 4.45395 4.78537 4.14195 6.68203C2.55728 6.7627 1.29395 8.06203 1.29395 9.6667C1.29395 11.3234 2.66699 12.6666 4.00033 12.6666" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.5" d="M2.66699 14L12.0003 4.66663" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>

        </div>
            Not supported in ClickHouse Cloud
        </div>;
};

This engine allows integrating ClickHouse with [RocksDB](http://rocksdb.org/).

<h2 id="creating-a-table">
  Creating a table
</h2>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE = EmbeddedRocksDB([ttl, rocksdb_dir, read_only]) PRIMARY KEY(primary_key_name)
[ SETTINGS name=value, ... ]
```

Engine parameters:

* `ttl` - time to live for values. TTL is accepted in seconds. If TTL is 0, regular RocksDB instance is used (without TTL).
* `rocksdb_dir` - path to the directory of an existed RocksDB or the destination path of the created RocksDB. Open the table with the specified `rocksdb_dir`.
* `read_only` - when `read_only` is set to true, read-only mode is used. For storage with TTL, compaction will not be triggered (neither manual nor automatic), so no expired entries are removed.
* `primary_key_name` – any column name in the column list.
* `primary key` must be specified, it supports only one column in the primary key. The primary key will be serialized in binary as a `rocksdb key`.
* columns other than the primary key will be serialized in binary as `rocksdb` value in corresponding order.
* queries with key `equals` or `in` filtering will be optimized to multi keys lookup from `rocksdb`.

Engine settings:

* `optimize_for_bulk_insert` – Table is optimized for bulk insertions (insert pipeline will create SST files and import to rocksdb database instead of writing to memtables); default value: `1`.
* `bulk_insert_block_size` - Minimum size of SST files (in term of rows) created by bulk insertion; default value: `1048449`.

Example:

```sql theme={null}
CREATE TABLE test
(
    `key` String,
    `v1` UInt32,
    `v2` String,
    `v3` Float32
)
ENGINE = EmbeddedRocksDB
PRIMARY KEY key
```

<h2 id="metrics">
  Metrics
</h2>

There is also `system.rocksdb` table, that expose rocksdb statistics:

```sql theme={null}
SELECT
    name,
    value
FROM system.rocksdb

┌─name──────────────────────┬─value─┐
│ no.file.opens             │     1 │
│ number.block.decompressed │     1 │
└───────────────────────────┴───────┘
```

<h2 id="configuration">
  Configuration
</h2>

You can also change any [rocksdb options](https://github.com/facebook/rocksdb/wiki/Option-String-and-Option-Map) using config:

```xml theme={null}
<rocksdb>
    <options>
        <max_background_jobs>8</max_background_jobs>
    </options>
    <column_family_options>
        <num_levels>2</num_levels>
    </column_family_options>
    <tables>
        <table>
            <name>TABLE</name>
            <options>
                <max_background_jobs>8</max_background_jobs>
            </options>
            <column_family_options>
                <num_levels>2</num_levels>
            </column_family_options>
        </table>
    </tables>
</rocksdb>
```

By default trivial approximate count optimization is turned off, which might affect the performance `count()` queries. To enable this
optimization set up `optimize_trivial_approximate_count_query = 1`. Also, this setting affects `system.tables` for EmbeddedRocksDB engine,
turn on the settings to see approximate values for `total_rows` and `total_bytes`.

<h2 id="supported-operations">
  Supported operations
</h2>

<h3 id="inserts">
  Inserts
</h3>

When new rows are inserted into `EmbeddedRocksDB`, if the key already exists, the value will be updated, otherwise a new key is created.

Example:

```sql theme={null}
INSERT INTO test VALUES ('some key', 1, 'value', 3.2);
```

<h3 id="deletes">
  Deletes
</h3>

Rows can be deleted using `DELETE` query or `TRUNCATE`.

```sql theme={null}
DELETE FROM test WHERE key LIKE 'some%' AND v1 > 1;
```

```sql theme={null}
ALTER TABLE test DELETE WHERE key LIKE 'some%' AND v1 > 1;
```

```sql theme={null}
TRUNCATE TABLE test;
```

<h3 id="updates">
  Updates
</h3>

Values can be updated using the `ALTER TABLE` query. The primary key cannot be updated.

```sql theme={null}
ALTER TABLE test UPDATE v1 = v1 * 10 + 2 WHERE key LIKE 'some%' AND v3 > 3.1;
```

<h3 id="joins">
  Joins
</h3>

A special `direct` join with EmbeddedRocksDB tables is supported.
This direct join avoids forming a hash table in memory and accesses
the data directly from the EmbeddedRocksDB.

With large joins you may see much lower memory usage with direct joins
because the hash table is not created.

To enable direct joins:

```sql theme={null}
SET join_algorithm = 'direct, hash'
```

<Tip>
  When the `join_algorithm` is set to `direct, hash`, direct joins will be used
  when possible, and hash otherwise.
</Tip>

<h4 id="example">
  Example
</h4>

<h5 id="create-and-populate-an-embeddedrocksdb-table">
  Create and populate an EmbeddedRocksDB table
</h5>

```sql theme={null}
CREATE TABLE rdb
(
    `key` UInt32,
    `value` Array(UInt32),
    `value2` String
)
ENGINE = EmbeddedRocksDB
PRIMARY KEY key
```

```sql theme={null}
INSERT INTO rdb
    SELECT
        toUInt32(sipHash64(number) % 10) AS key,
        [key, key+1] AS value,
        ('val2' || toString(key)) AS value2
    FROM numbers_mt(10);
```

<h5 id="create-and-populate-a-table-to-join-with-table-rdb">
  Create and populate a table to join with table `rdb`
</h5>

```sql theme={null}
CREATE TABLE t2
(
    `k` UInt16
)
ENGINE = TinyLog
```

```sql theme={null}
INSERT INTO t2 SELECT number AS k
FROM numbers_mt(10)
```

<h5 id="set-the-join-algorithm-to-direct">
  Set the join algorithm to `direct`
</h5>

```sql theme={null}
SET join_algorithm = 'direct'
```

<h5 id="an-inner-join">
  An INNER JOIN
</h5>

```sql theme={null}
SELECT *
FROM
(
    SELECT k AS key
    FROM t2
) AS t2
INNER JOIN rdb ON rdb.key = t2.key
ORDER BY key ASC
```

```response theme={null}
┌─key─┬─rdb.key─┬─value──┬─value2─┐
│   0 │       0 │ [0,1]  │ val20  │
│   2 │       2 │ [2,3]  │ val22  │
│   3 │       3 │ [3,4]  │ val23  │
│   6 │       6 │ [6,7]  │ val26  │
│   7 │       7 │ [7,8]  │ val27  │
│   8 │       8 │ [8,9]  │ val28  │
│   9 │       9 │ [9,10] │ val29  │
└─────┴─────────┴────────┴────────┘
```

<h3 id="more-information-on-joins">
  More information on Joins
</h3>

* [`join_algorithm` setting](/reference/settings/session-settings#join_algorithm)
* [JOIN clause](/reference/statements/select/join)
