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
This is an umbrella issue to track performance issues, collect ideas, and document improvements as well as latest update. It can also be used for other purposes like evaluating ClickHouse client, understanding how slow Java lib is and why.
Issues
#
Module
Issue
Workaround
1
clickhouse-client
CPU was not fully utilized in query
Change bufferingMode to PERFORMANCE to spawn one more thread for compression/decompression
2
clickhouse-jdbc
Slow SQL parsing
Use Java client or avoid passing large SQL to JDBC driver
3
clickhouse-jdbc
Slow batch insert and high memory usage when dealing large data volume
Use Java client or multi-threading
4
clickhouse-jdbc
Query for initializing JDBC connection
set server_time_zone and server_version in connection string or properties to skip that
GraalVM for less startup time (mainly for testing)
Serialization
Add ByteUtils along with unsafe implementation
Introduce ByteBudy / asm to generate compact code without unnecessary checks / method calls
New ByteUtils implementation on top of Vector API for JDK 17+
Streaming
Direct write instead of piped stream
DirectBuffer if possible
Zero-copy for direct file-based streaming(e.g. ClickHouseClient.dump() and ClickHouseClient.load()), if possible
Test Environment
Two KVMs on same host, one as ClickHouse server and the other as test client.
VM
vCPU
MEM
O/S
Software
ch-server
4
16GB
fedora 6.1.9-100.fc36.x86_64
clickhouse-server 22.8.13.20
test-client
4
16GB
fedora 6.1.9-100.fc36.x86_64
clickhouse-client 22.8.13.20 & Open JDK 17.0.5
Note: the host is a PC server(O/S: Fedora 36 server, CPU: 24x 12th Gen Intel(R) Core(TM) i9-12900T, MEM: 2 x 32 GB DDR4, SSD). iperf3 shows ~75.6 Gbits/sec bitrate between the two VMs.
Query Time
Measure elapsed time and resource usage at client side. To understand the gaps:
Protocol Discrepancy(http vs. tcp/native) - curl vs. clickhouse-client
Streaming Efficiency - curl vs. Java(dump/load)
Deserialization Cost - Java(dump) vs. Java(custom)
Serialization Cost - Java(load) vs. Java(write)
Encapsulation Overhead & Poor Implementation - Java(custom) vs. Java(default) and Java(default/write) vs. JDBC
About the test...
Steps
restart ClickHouse server and sleep 10 seconds for each case
execute same case consecutively 5 times with 5-second interval
pick the median elapsed time as result
Queries
Query
SQL
Int8
select (number % 256)::Int8 v from numbers(500000000)
UInt64
select * from numbers(500000000)
String
select toString(number) from numbers(500000000)
Mixed
select (number % 256)::Int8 a, number b, toString(number) c from numbers(300000000)
curl - A command-line tool for transferring data specified with URL syntax
# read - when compression is 1, compress_header_opt will be "-H 'Accept-Encoding: lz4'"
curl -s -u "$db_user:$db_passwd" --get --data-urlencode "compress=$compression" \
--data-urlencode "query=$query"$compress_header_opt \
-H "X-ClickHouse-Format: $format""http://$db_host:$db_http_port">$outfile# write - don't use -d @file or it will end up with OOM error
curl -s -u "$db_user:$db_passwd" -X POST -H "X-ClickHouse-Database: $db_name" -H "Transfer-Encoding: chunked" -T $outfile \
"http://$db_host:$db_http_port/?query=insert%20into%20test_load%20format%20$format&decompress=$compression"
Java(dump) - Java client to dump query result without decompression and deserialization
// readtry (Connectionconn = driver.connect(url, props); Statementstmt = conn.createStatement();
ResultSetrs = stmt.executeQuery(query)) {
intcount = 0;
byteb = (byte) 0;
longl = 0L;
Strings = "";
rs.unwrap(ClickHouseResponse.class).getInputStream().setCopyToTarget(out);
while (rs.next()) {
b = rs.getByte(1);
l = rs.getLong(2);
s = rs.getString(3);
count++;
}
if (count > (0xFF & b) && count > l && count > s.length()) {
out.flush();
}
}
// write - batch insertStringinsertQuery = "insert into test_load values(?,?,?)"; // or insert into test_load values(?) for other casesintrange = 300000000; // 500000000 for Int8, UInt64 and Stringtry (Connectionconn = driver.connect(url, props); PreparedStatementps = conn.prepareStatement(insertQuery)) {
intbatchSize = 100000;
intcount = 0;
for (inti = 0; i < range; i++) {
ps.setByte(1, (byte) (i % 256));
ps.setLong(2, i);
ps.setString(3, Integer.toString(i));
ps.addBatch();
if ((count = i % batchSize) == 0) {
ps.executeBatch();
}
}
if (count > 0) {
ps.executeBatch();
}
}
Read & Write
lz4
none
Mode
Client
Format
Case
ElapsedTime
CPU%
MEM(MB)
ElapsedTime
CPU%
MEM(MB)
Read
clickhouse-client
Native
Int8
0.39
52%
107.39
0.44
53%
107.66
Mixed
8.46
84%
112.74
4.79
91%
112.51
String
9.23
75%
110.92
5.44
96%
110.02
UInt64
5.41
85%
109.1
1.59
99%
109.06
RowBinary
Int8
1.25
387%
109.55
1.3
386%
109.5
Mixed
8.69
151%
135.3
4.38
252%
134.85
String
9.34
108%
118.56
4.13
209%
118.12
UInt64
5.11
181%
111.93
2.86
200%
112.25
curl
Native
Int8
0.35
2%
9.01
0.71
49%
8.78
Mixed
10.1
9%
8.96
6.15
41%
8.92
String
11.41
7%
8.97
6.57
32%
8.82
UInt64
5.33
16%
8.87
2.09
91%
8.8
RowBinary
Int8
1.27
0%
8.83
1.42
20%
8.86
Mixed
5.75
13%
8.86
4.8
58%
8.85
String
8.26
11%
8.87
5.26
49%
8.95
UInt64
6.1
17%
8.89
3.02
68%
8.93
Java Client(custom)
RowBinaryWithNamesAndTypes
Int8
1.94
68%
66.88
1.69
79%
69.18
Mixed
9.99
102%
265.53
8.43
102%
360.99
String
13.53
86%
328.16
10.42
92%
405.59
UInt64
6.84
104%
211.25
4.48
105%
102.79
Java Client(deser)
RowBinaryWithNamesAndTypes
Int8
3.48
95%
67.42
3.41
102%
66.71
Mixed
14.63
96%
214.33
13.21
99%
259.7
String
14.45
102%
266.73
13.48
95%
260.09
UInt64
9.07
104%
212.3
7.13
102%
99.25
Java Client(dump)
Native
Int8
0.46
51%
55.39
0.92
161%
112.65
Mixed
10.55
18%
71.19
6.18
74%
101.36
String
11.68
14%
71.49
8.27
49%
108.95
UInt64
5.64
30%
69.58
3.95
75%
109.5
RowBinaryWithNamesAndTypes
Int8
1.4
17%
55.83
1.72
46%
62.3
Mixed
5.72
35%
96.98
5.64
94%
138
String
8.72
23%
78.37
6.15
68%
82.48
UInt64
5.8
34%
99.35
4.46
77%
117.42
Java Client(read)
RowBinaryWithNamesAndTypes
Int8
2.8
95%
67.6
2.85
104%
69.49
Mixed
18.05
94%
215.16
13.22
99%
206.48
String
14.09
102%
268.16
13.31
91%
261.98
UInt64
8.3
103%
213.43
5.8
104%
104.67
JDBC Driver
RowBinaryWithNamesAndTypes
Int8
4.95
97%
72.24
5.2
102%
69
Mixed
16.69
95%
212.74
15.05
100%
209.39
String
16.3
101%
266.23
15.72
92%
261.5
UInt64
11.68
102%
212.85
9.21
102%
107.32
Write
clickhouse-client
Native
Int8
0.18
57%
1.94
0.65
19%
1.95
Mixed
18.9
7%
1.95
16.66
10%
1.94
String
2.69
37%
1.94
5.2
18%
1.94
UInt64
1.45
62%
1.94
3.25
31%
1.94
RowBinary
Int8
7.52
2%
1.94
7.56
3%
1.94
Mixed
16.56
5%
1.94
17.73
7%
1.94
String
19.34
7%
1.94
18.5
7%
1.94
UInt64
13.66
7%
1.94
11.83
9%
1.95
curl
Native
Int8
0.47
0%
8.92
0.58
20%
8.85
Mixed
16.49
3%
8.82
16.94
6%
8.82
String
6.4
6%
8.92
8.1
8%
8.91
UInt64
5.51
8%
8.78
2.77
38%
8.87
RowBinary
Int8
7.55
0%
8.9
7.75
1%
8.84
Mixed
23.48
2%
8.85
23.51
5%
8.89
String
22.76
1%
8.91
23.51
3%
8.89
UInt64
16.86
3%
8.94
15.93
6%
8.88
Java Client(load)
Native
Int8
0.59
37%
54.9
0.67
76%
59.87
Mixed
16.88
9%
62.66
15.95
18%
58.67
String
6.75
18%
60.12
5.81
48%
56.61
UInt64
7.61
15%
60
5.29
49%
56.42
RowBinaryWithNamesAndTypes
Int8
7.74
3%
55.86
7.84
7%
60.35
Mixed
23.39
5%
60.46
23.67
13%
57.86
String
24.56
5%
60.24
21.8
13%
59.41
UInt64
17.56
7%
59.42
14.75
15%
56.61
Java Client(write)
RowBinaryWithNamesAndTypes
Int8
7.71
36%
214.87
7.87
27%
213.43
Mixed
27.65
98%
347.98
25.43
77%
265.56
String
26.46
114%
350.92
24.63
77%
276.4
UInt64
21.25
86%
350.57
16.23
47%
210.88
JDBC Driver(batch)
RowBinaryWithNamesAndTypes
Int8
14.52
49%
213.21
14.34
50%
198.91
Mixed
44.58
67%
462.6
42.03
52%
366.8
String
42.61
73%
399.83
39.25
54%
351.37
UInt64
29.62
71%
405.58
25.06
48%
295.75
JDBC Driver(load)
Native
Int8
0.63
48%
60.55
0.74
87%
65.6
Mixed
19.97
8%
64.8
16.93
22%
65.15
String
8.42
16%
66.14
5.96
48%
64.26
UInt64
5.71
24%
64.43
5.83
44%
64.71
RowBinaryWithNamesAndTypes
Int8
7.74
4%
60.39
7.88
7%
62.55
Mixed
25.52
5%
63.84
24.04
12%
65.52
String
25.2
6%
64.14
23.77
12%
64.41
UInt64
18.86
7%
64.67
15.55
16%
65.05
Throughput (ops/s)
TODO
Pitfalls
Protocol matters the most
Large SQL statement
Batch insert
Improvements
0.4.0
Remove deprecated code and refactor data processor #1124
Overall improvement in both deserialization and serialization. String deserialization now requires less memory and is ~30% faster. However, many breaking changes were involved and binary string support is disabled by default.
This is an umbrella issue to track performance issues, collect ideas, and document improvements as well as latest update. It can also be used for other purposes like evaluating ClickHouse client, understanding how slow Java lib is and why.
Issues
server_time_zone
andserver_version
in connection string or properties to skip thatTODOs
Test Environment
Two KVMs on same host, one as ClickHouse server and the other as test client.
Note: the host is a PC server(O/S: Fedora 36 server, CPU: 24x 12th Gen Intel(R) Core(TM) i9-12900T, MEM: 2 x 32 GB DDR4, SSD). iperf3 shows ~75.6 Gbits/sec bitrate between the two VMs.
Query Time
Measure elapsed time and resource usage at client side. To understand the gaps:
About the test...
Steps
Queries
Clients
Read & Write
Throughput (ops/s)
TODO
Pitfalls
Improvements
Overall improvement in both deserialization and serialization. String deserialization now requires less memory and is ~30% faster. However, many breaking changes were involved and binary string support is disabled by default.
Array deserialization is twice faster than it was in 0.3.2*.
References
The text was updated successfully, but these errors were encountered: