You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/best-practices/json_type.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ description: 'Page describing when to use JSON'
8
8
9
9
ClickHouse now offers a native JSON column type designed for semi-structured and dynamic data. It's important to clarify that **this is a column type, not a data format**—you can insert JSON into ClickHouse as a string or via supported formats like [JSONEachRow](/docs/interfaces/formats/JSONEachRow), but that does not imply using the JSON column type. Users should only use the JSON type when the structure of their data is dynamic, not when they simply happen to store JSON.
10
10
11
-
## When to Use the JSON Type {#when-to-use-the-json-type}
11
+
## When to use the JSON type {#when-to-use-the-json-type}
12
12
13
13
Use the JSON type when your data:
14
14
@@ -24,7 +24,7 @@ If your data structure is known and consistent, there is rarely a need for the J
24
24
25
25
You can also mix approaches - for example, use static columns for predictable top-level fields and a single JSON column for a dynamic section of the payload.
26
26
27
-
## Considerations and Tips for Using JSON {#considerations-and-tips-for-using-json}
27
+
## Considerations and tips for using JSON {#considerations-and-tips-for-using-json}
28
28
29
29
The JSON type enables efficient columnar storage by flattening paths into subcolumns. But with flexibility comes responsibility. To use it effectively:
30
30
@@ -33,14 +33,14 @@ The JSON type enables efficient columnar storage by flattening paths into subcol
33
33
***Avoid setting [`max_dynamic_paths`](/sql-reference/data-types/newjson#reaching-the-limit-of-dynamic-paths-inside-json) too high** - large values increase resource consumption and reduce efficiency. As a rule of thumb, keep it below 10,000.
34
34
35
35
:::note Type hints
36
-
Type hits offer more than just a way to avoid unnecessary type inference - they eliminate storage and processing indirection entirely. JSON paths with type hints are always stored just like traditional columns, bypassing the need for [**discriminator columns**](https://clickhouse.com/blog/a-new-powerful-json-data-type-for-clickhouse#storage-extension-for-dynamically-changing-data) or dynamic resolution during query time. This means that with well-defined type hints, JSON subfields achieve the same performance and efficiency as if they were modeled as top-level fields from the outset. As a result, for datasets that are mostly consistent but still benefit from the flexibility of JSON, type hints provide a convenient way to preserve performance without needing to restructure your schema or ingest pipeline.
36
+
Type hits offer more than just a way to avoid unnecessary type inference - they eliminate storage and processing indirection entirely. JSON paths with type hints are always stored just like traditional columns, bypassing the need for [**discriminator columns**](https://clickhouse.com/blog/a-new-powerful-json-data-type-for-clickhouse#storage-extension-for-dynamically-changing-data) or dynamic resolution during query time. This means that with well-defined type hints, nested JSON fields achieve the same performance and efficiency as if they were modeled as top-level fields from the outset. As a result, for datasets that are mostly consistent but still benefit from the flexibility of JSON, type hints provide a convenient way to preserve performance without needing to restructure your schema or ingest pipeline.
37
37
:::
38
38
39
39
## Advanced Features {#advanced-features}
40
40
41
41
* JSON columns **can be used in primary keys** like any other columns. Codecs cannot be specified for a sub-column.
42
42
* They support introspection via functions like [`JSONAllPathsWithTypes()` and `JSONDynamicPaths()`](/sql-reference/data-types/newjson#introspection-functions).
43
-
* You can read nested sub-objects using the .^ syntax.
43
+
* You can read nested sub-objects using the `.^` syntax.
44
44
* Query syntax may differ from standard SQL and may require special casting or operators for nested fields.
45
45
46
46
For additional guidance, see[ ClickHouse JSON documentation](/sql-reference/data-types/newjson) or explore our blog post[ A New Powerful JSON Data Type for ClickHouse](https://clickhouse.com/blog/a-new-powerful-json-data-type-for-clickhouse).
@@ -62,7 +62,7 @@ Consider the following JSON sample, representing a row from the [Python PyPI dat
62
62
}
63
63
```
64
64
65
-
Lets assume this schema is static and the types can be well defined. Even if the data is in NDJSON format (json row per line), there is no need to use the JSON type for such a schema. Simply define the schema with classic types.
65
+
Lets assume this schema is static and the types can be well defined. Even if the data is in NDJSON format (JSON row per line), there is no need to use the JSON type for such a schema. Simply define the schema with classic types.
66
66
67
67
```sql
68
68
CREATETABLEpypi (
@@ -153,7 +153,7 @@ INSERT INTO arxiv FORMAT JSONEachRow
153
153
{"id":"2101.11408","submitter":"Daniel Lemire","authors":"Daniel Lemire","title":"Number Parsing at a Gigabyte per Second","comments":"Software at https://github.com/fastfloat/fast_float and\n https://github.com/lemire/simple_fastfloat_benchmark/","journal-ref":"Software: Practice and Experience 51 (8), 2021","doi":"10.1002/spe.2984","report-no":null,"categories":"cs.DS cs.MS","license":"http://creativecommons.org/licenses/by/4.0/","abstract":"With disks and networks providing gigabytes per second ....\n","versions":[{"created":"Mon, 11 Jan 2021 20:31:27 GMT","version":"v1"},{"created":"Sat, 30 Jan 2021 23:57:29 GMT","version":"v2"}],"update_date":"2022-11-07","authors_parsed":[["Lemire","Daniel",""]]}
154
154
```
155
155
156
-
Suppose another column is added `tags`. If this was simply a list of strings we could model as an `Array(String)`, but let's assume users can add arbitrary tag structures with mixed types (notice score is a string or integer). Our modified JSON document:
156
+
Suppose another column called `tags` is added. If this was simply a list of strings we could model as an `Array(String)`, but let's assume users can add arbitrary tag structures with mixed types (notice score is a string or integer). Our modified JSON document:
Copy file name to clipboardExpand all lines: docs/best-practices/minimize_optimize_joins.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,7 +26,7 @@ For a full guide on denormalizing data in ClickHouse see [here](/data-modeling/d
26
26
27
27
## When JOINs are required {#when-joins-are-required}
28
28
29
-
When JOINs are required, ensure you're using **at least 24.12 and preferably the latest**, as JOIN performance continues to improve. As of ClickHouse 24.12, the query planner now automatically places the smaller table on the right side of the join for optimal performance - a task that previously had to be done manually. Even more enhancements are coming soon, including more aggressive filter pushdown and automatic re-ordering of multiple joins.
29
+
When JOINs are required, ensure you’re using **at least version 24.12 and preferably the latest version**, as JOIN performance continues to improve with each new release. As of ClickHouse 24.12, the query planner now automatically places the smaller table on the right side of the join for optimal performance - a task that previously had to be done manually. Even more enhancements are coming soon, including more aggressive filter pushdown and automatic re-ordering of multiple joins.
30
30
31
31
Follow these best practices to improve JOIN performance:
32
32
@@ -44,13 +44,13 @@ When using dictionaries for JOINs in ClickHouse, it's important to understand th
44
44
45
45
## Choosing the right JOIN Algorithm {#choosing-the-right-join-algorithm}
46
46
47
-
ClickHouse supports several join algorithms that trade off between speed and memory:
47
+
ClickHouse supports several JOIN algorithms that trade off between speed and memory:
48
48
49
49
***Parallel Hash JOIN (default):** Fast for small-to-medium right-hand tables that fit in memory.
50
50
***Direct JOIN:** Ideal when using dictionaries (or other table engines with key-value characteristics) with `INNER` or `LEFT ANY JOIN` - the fastest method for point lookups as it eliminates the need to build a hash table.
51
51
***Full Sorting Merge JOIN:** Efficient when both tables are sorted on the join key.
52
52
***Partial Merge JOIN:** Minimizes memory but is slower—best for joining large tables with limited memory.
53
-
***Grace Hash JOIN:** Flexible and can memory-tunable, good for large datasets with adjustable performance characteristics.
53
+
***Grace Hash JOIN:** Flexible and memory-tunable, good for large datasets with adjustable performance characteristics.
54
54
55
55
<Imageimg={joins}size="md"alt="Joins - speed vs memory"/>
56
56
@@ -66,4 +66,4 @@ For optimal performance:
66
66
* Avoid more than 3–4 joins per query.
67
67
* Benchmark different algorithms on real data - performance varies based on JOIN key distribution and data size.
68
68
69
-
For more on JOIN optimization strategies, join algorithms, and how to tune them, refer to the[ ClickHouse documentation](/guides/joining-tables) and this [blog series](https://clickhouse.com/blog/clickhouse-fully-supports-joins-part1).
69
+
For more on JOIN optimization strategies, JOIN algorithms, and how to tune them, refer to the[ ClickHouse documentation](/guides/joining-tables) and this [blog series](https://clickhouse.com/blog/clickhouse-fully-supports-joins-part1).
Copy file name to clipboardExpand all lines: docs/best-practices/partionning_keys.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -46,19 +46,19 @@ With partitioning enabled, ClickHouse only [merges](/merges) data parts within,
46
46
47
47
## Applications of partitioning {#applications-of-partionning}
48
48
49
-
Partitioning is a powerful tool for managing large datasets in ClickHouse, especially in observability and analytics use cases. It enables efficient data life cycle operations by allowing entire partitions, often aligned with time or business logic, to be dropped, moved, or archived in a single metadata operation. This is significantly faster and less resource-intensive than row-level deletes or copy operations. Partitioning also integrates cleanly with ClickHouse features like TTL and tiered storage, making it possible to implement retention policies or hot/cold storage strategies without custom orchestration. For example, recent data can be kept on fast SSD-backed storage, while older partitions are automatically moved to cheaper object storage.
49
+
Partitioning is a powerful tool for managing large datasets in ClickHouse, especially in observability and analytics use cases. It enables efficient data life cycle operations by allowing entire partitions, often aligned with time or business logic, to be dropped, moved, or archived in a single metadata operation. This is significantly faster and less resource-intensive than row-level delete or copy operations. Partitioning also integrates cleanly with ClickHouse features like TTL and tiered storage, making it possible to implement retention policies or hot/cold storage strategies without custom orchestration. For example, recent data can be kept on fast SSD-backed storage, while older partitions are automatically moved to cheaper object storage.
50
50
51
51
While partitioning can improve query performance for some workloads, it can also negatively impact response time.
52
52
53
53
If the partitioning key is not in the primary key and you are filtering by it, users may see an improvement in query performance with partitioning. See [here](/partitions#query-optimization) for an example.
54
54
55
55
Conversely, if queries need to query across partitions performance may be negatively impacted due to a higher number of total parts. For this reason, users should understand their access patterns before considering partitioning a a query optimization technique.
56
56
57
-
In summary, users should primarily think of partitioning as a data management technique. For an example of managing data, see [here](/observability/managing-data) and [here](/partitions#data-management).
57
+
In summary, users should primarily think of partitioning as a data management technique. For an example of managing data, see ["Managing Data"](/observability/managing-data)from the observability use-case guide and ["What are table partitions used for?"](/partitions#data-management) from Core Concepts - Table partitions.
58
58
59
59
## Choose a low cardinality partitioning key {#choose-a-low-cardinality-partitioning-key}
60
60
61
-
Importantly, a higher number of parts will negatively affect query performance. ClickHouse will therefore respond to inserts with a [“too many parts”](/knowledgebase/exception-too-many-parts) error if the number of parts exceeds [limits either in total](/operations/settings/merge-tree-settings#max_parts_in_total) or [per partition](/operations/settings/merge-tree-settings#parts_to_throw_insert).
61
+
Importantly, a higher number of parts will negatively affect query performance. ClickHouse will therefore respond to inserts with a [“too many parts”](/knowledgebase/exception-too-many-parts) error if the number of parts exceeds specified limits either in [total](/operations/settings/merge-tree-settings#max_parts_in_total) or [per partition](/operations/settings/merge-tree-settings#parts_to_throw_insert).
62
62
63
63
Choosing the right **cardinality** for the partitioning key is critical. A high-cardinality partitioning key - where the number of distinct partition values is large - can lead to a proliferation of data parts. Since ClickHouse does not merge parts across partitions, too many partitions will result in too many unmerged parts, eventually triggering the “Too many parts” error. [Merges are essential](/merges) for reducing storage fragmentation and optimizing query speed, but with high-cardinality partitions, that merge potential is lost.
Copy file name to clipboardExpand all lines: docs/best-practices/selecting_an_insert_strategy.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,10 +12,10 @@ import async_inserts from '@site/static/images/bestpractices/async_inserts.png';
12
12
import AsyncInserts from '@site/docs/best-practices/_snippets/_async_inserts.md';
13
13
import BulkInserts from '@site/docs/best-practices/_snippets/_bulk_inserts.md';
14
14
15
-
Efficient data ingestion is a basis of high-performance ClickHouse deployments. Selecting the right insert strategy can dramatically impact throughput, cost, and reliability. This section outlines best practices, tradeoffs, and configuration options to help you make the right decision for your workload.
15
+
Efficient data ingestion forms the basis of high-performance ClickHouse deployments. Selecting the right insert strategy can dramatically impact throughput, cost, and reliability. This section outlines best practices, tradeoffs, and configuration options to help you make the right decision for your workload.
16
16
17
17
:::note
18
-
The following assumes you are pushing data to ClickHouse via a client. If you are pulling data into ClickHouse e.g. using built in table functions such as [s3](/sql-reference/table-functions/s3) and [gcs](/sql-reference/table-functions/gcs), we recommend [this guide](/integrations/s3/performance).
18
+
The following assumes you are pushing data to ClickHouse via a client. If you are pulling data into ClickHouse e.g. using built in table functions such as [s3](/sql-reference/table-functions/s3) and [gcs](/sql-reference/table-functions/gcs), we recommend our guide["Optimizing for S3 Insert and Read Performance"](/integrations/s3/performance).
19
19
:::
20
20
21
21
## Synchronous inserts by default {#synchronous-inserts-by-default}
@@ -53,7 +53,7 @@ Using the values from that formatted data and the target table's [DDL](/sql-refe
Synchronous inserts are also **idempotent**. When using MergeTree engines, ClickHouse will deduplicate inserts by default. This protects against ambiguous failure cases, such as:
59
59
@@ -67,7 +67,7 @@ In both cases, it's safe to **retry the insert** - as long as the batch contents
67
67
For sharded clusters, you have two options:
68
68
69
69
* Insert directly into a **MergeTree** or **ReplicatedMergeTree** table. This is the most efficient option when the client can perform load balancing across shards. With `internal_replication = true`, ClickHouse handles replication transparently.
70
-
* Insert into a Distributed table. This allows clients to send data to any node and let ClickHouse forward it to the correct shard. This is simpler but slightly less performant due to the extra forwarding step. `internal_replication = true` is still recommended.
70
+
* Insert into a [Distributed table](/engines/table-engines/special/distributed). This allows clients to send data to any node and let ClickHouse forward it to the correct shard. This is simpler but slightly less performant due to the extra forwarding step. `internal_replication = true` is still recommended.
71
71
72
72
**In ClickHouse Cloud all nodes read and write to the same single shard. Inserts are automatically balanced across nodes. Users can simply send inserts to the exposed endpoint.**
73
73
@@ -89,7 +89,7 @@ Compressing insert data reduces the size of the payload sent over the network, m
89
89
90
90
For inserts, compression is especially effective when used with the Native format, which already matches ClickHouse's internal columnar storage model. In this setup, the server can efficiently decompress and directly store the data with minimal transformation.
91
91
92
-
#### Use LZ4 for Speed, ZSTD for Compression Ratio {#use-lz4-for-speed-zstd-for-compression-ratio}
92
+
#### Use LZ4 for speed, ZSTD for compression ratio {#use-lz4-for-speed-zstd-for-compression-ratio}
93
93
94
94
ClickHouse supports several compression codecs during data transmission. Two common options are:
95
95
@@ -102,7 +102,7 @@ Best practice: Use LZ4 unless you have constrained bandwidth or incur data egres
102
102
In tests from the [FastFormats benchmark](https://clickhouse.com/blog/clickhouse-input-format-matchup-which-is-fastest-most-efficient), LZ4-compressed Native inserts reduced data size by more than 50%, cutting ingestion time from 150s to 131s for a 5.6 GiB dataset. Switching to ZSTD compressed the same dataset down to 1.69 GiB, but increased server-side processing time slightly.
Compression not only reduces network traffic—it also improves CPU and memory efficiency on the server. With compressed data, ClickHouse receives fewer bytes and spends less time parsing large inputs. This benefit is especially important when ingesting from multiple concurrent clients, such as in observability scenarios.
0 commit comments