ClickHouseInc

ClickHouse 官方文档:处理 JSON 数据 (2/2)

Image

本文字数:15445;估计阅读时间:39分钟

ClickHouse 官方文档:处理 JSON 数据 (1/2)

2025-01-02

Image

Image

导出 JSON 数据和元信息  

用于导入的几乎所有 JSON 格式都可以用于导出。最常用的导出格式是 JSONEachRow:

SELECT * FROM sometable FORMAT JSONEachRow
{"path":"Bob_Dolman","month":"2016-11-01","hits":245}{"path":"1-krona","month":"2017-01-01","hits":4}{"path":"Ahmadabad-e_Kalij-e_Sofla","month":"2017-01-01","hits":3}

此外,可以使用 JSONCompactEachRow 格式,通过省略列名来减少存储空间占用:

SELECT * FROM sometable FORMAT JSONCompactEachRow
["Bob_Dolman", "2016-11-01", 245]["1-krona", "2017-01-01", 4]["Ahmadabad-e_Kalij-e_Sofla", "2017-01-01", 3]

将数据类型导出为字符串  

ClickHouse 会严格按照标准遵循数据类型导出 JSON。但在某些场景中,如果需要将所有值导出为字符串,可以使用 JSONStringsEachRow 格式:

SELECT * FROM sometable FORMAT JSONStringsEachRow
{"path":"Bob_Dolman","month":"2016-11-01","hits":"245"}{"path":"1-krona","month":"2017-01-01","hits":"4"}{"path":"Ahmadabad-e_Kalij-e_Sofla","month":"2017-01-01","hits":"3"}

在此示例中,数值列 hits 被编码为字符串。此功能适用于所有 JSON* 格式,用户可以使用 JSONStrings\* 或 JSONCompactStrings\* 格式:

SELECT * FROM sometable FORMAT JSONCompactStringsEachRow
["Bob_Dolman", "2016-11-01", "245"]["1-krona", "2017-01-01", "4"]["Ahmadabad-e_Kalij-e_Sofla", "2017-01-01", "3"]

导出数据及元信息  

通用 JSON 格式(广泛应用于各种应用程序)不仅会导出结果数据,还包含列类型和查询统计信息:

SELECT * FROM sometable FORMAT JSON
{    "meta":    [        {            "name": "path",            "type": "String"        },        …    ],
"data": [ { "path": "Bob_Dolman", "month": "2016-11-01", "hits": 245 }, … ],
"rows": 3,
"statistics": { "elapsed": 0.000497457, "rows_read": 3, "bytes_read": 87 }}

JSONCompact 格式提供相同的元信息,但对数据部分采用紧凑格式:

SELECT * FROM sometable FORMAT JSONCompact
{    "meta":    [        {            "name": "path",            "type": "String"        },        …    ],
"data": [ ["Bob_Dolman", "2016-11-01", 245], ["1-krona", "2017-01-01", 4], ["Ahmadabad-e_Kalij-e_Sofla", "2017-01-01", 3] ],
"rows": 3,
"statistics": { "elapsed": 0.00074981, "rows_read": 3, "bytes_read": 87 }}

如果需要将所有值导出为字符串,可以选择 JSONStrings 或 JSONCompactStrings 格式变体。

紧凑格式导出 JSON 数据  

导出 JSON 数据及其结构的更高效方式是使用 JSONCompactEachRowWithNamesAndTypes 格式:

SELECT * FROM sometable FORMAT JSONCompactEachRowWithNamesAndTypes
["path", "month", "hits"]["String", "Date", "UInt32"]["Bob_Dolman", "2016-11-01", 245]["1-krona", "2017-01-01", 4]["Ahmadabad-e_Kalij-e_Sofla", "2017-01-01", 3]

该格式采用紧凑的 JSON 表示,并附加两行头部信息,分别包含列名和列类型。此格式非常适合导入到其他 ClickHouse 实例或应用程序。

将 JSON 数据导出到文件  

可以使用 INTO OUTFILE 子句将 JSON 数据保存到文件中:

SELECT * FROM sometable INTO OUTFILE 'out.json' FORMAT JSONEachRow
36838935 rows in set. Elapsed: 2.220 sec. Processed 36.84 million rows, 1.27 GB (16.60 million rows/s., 572.47 MB/s.)

ClickHouse 在 2 秒内成功导出了约 3700 万条记录至 JSON 文件。此外,还可以通过 COMPRESSION 子句启用实时压缩:

SELECT * FROM sometable INTO OUTFILE 'out.json.gz' FORMAT JSONEachRow
36838935 rows in set. Elapsed: 22.680 sec. Processed 36.84 million rows, 1.27 GB (1.62 million rows/s., 56.02 MB/s.)

尽管压缩过程耗时更长,但生成的文件大小显著减小:

2.2G    out.json576M    out.json.gz

Image

处理其他 JSON 格式  

在前面的示例中,我们使用 JSONEachRow(NDJSON)格式加载 JSON 数据。以下是其他常见 JSON 格式的加载方法。

JSON 对象数组  

常见的一种 JSON 数据格式是数组形式的 JSON 对象列表,如以下示例:

> cat list.json[  {    "path": "Akiba_Hebrew_Academy",    "month": "2017-08-01",    "hits": 241  },  {    "path": "Aegithina_tiphia",    "month": "2018-02-01",    "hits": 34  },  ...]

可以为此类数据定义一个表:

CREATE TABLE sometable(    `path` String,    `month` Date,    `hits` UInt32)ENGINE = MergeTreeORDER BY tuple(month, path)

导入 JSON 对象列表时,可以使用 JSONEachRow 格式(从本地文件 list.json 加载数据):

INSERT INTO sometableFROM INFILE 'list.json'FORMAT JSONEachRow

使用 FROM INFILE 子句从本地文件加载数据,导入成功:

SELECT *FROM sometable
┌─path──────────────────────┬──────month─┬─hits─┐│ 1971-72_Utah_Stars_season │ 2016-10-01 │    1 ││ Akiba_Hebrew_Academy      │ 2017-08-01 │  241 ││ Aegithina_tiphia          │ 2018-02-01 │   34 │└───────────────────────────┴────────────┴──────┘

处理 NDJSON(行分隔 JSON)  

许多应用会将日志记录为 JSON 格式,每行表示一个独立的 JSON 对象,如以下文件所示:

cat object-per-line.json
{"path":"1-krona","month":"2017-01-01","hits":4}{"path":"Ahmadabad-e_Kalij-e_Sofla","month":"2017-01-01","hits":3}{"path":"Bob_Dolman","month":"2016-11-01","hits":245}

JSONEachRow 格式也适用于此类文件:

INSERT INTO sometable FROM INFILE 'object-per-line.json' FORMAT JSONEachRow;SELECT * FROM sometable;
┌─path──────────────────────┬──────month─┬─hits─┐│ Bob_Dolman                │ 2016-11-01 │  245 ││ 1-krona                   │ 2017-01-01 │    4 ││ Ahmadabad-e_Kalij-e_Sofla │ 2017-01-01 │    3 │└───────────────────────────┴────────────┴──────┘

JSON 对象键  

在某些场景下,JSON 对象列表可能以对象属性的形式编码,而非数组元素(例如 objects.json 文件):

cat objects.json
{  "a": {    "path":"April_25,_2017",    "month":"2018-01-01",    "hits":2  },  "b": {    "path":"Akahori_Station",    "month":"2016-06-01",    "hits":11  },  ...}

ClickHouse 支持使用 JSONObjectEachRow 格式加载此类数据:

INSERT INTO sometable FROM INFILE 'objects.json' FORMAT JSONObjectEachRow;SELECT * FROM sometable;
┌─path────────────┬──────month─┬─hits─┐│ Abducens_palsy  │ 2016-05-01 │   28 ││ Akahori_Station │ 2016-06-01 │   11 ││ April_25,_2017  │ 2018-01-01 │    2 │└─────────────────┴────────────┴──────┘

指定父对象键值  

如果需要将父对象的键值保存到表中,可以使用以下选项定义目标列名:

SET format_json_object_each_row_column_for_object_name = 'id'

随后,可以通过 file() 函数检查从原始 JSON 文件加载的数据:

SELECT * FROM file('objects.json', JSONObjectEachRow)
┌─id─┬─path────────────┬──────month─┬─hits─┐│ a  │ April_25,_2017  │ 2018-01-01 │    2 ││ b  │ Akahori_Station │ 2016-06-01 │   11 ││ c  │ Abducens_palsy  │ 2016-05-01 │   28 │└────┴─────────────────┴────────────┴──────┘

可以看到,id 列已成功填充对应的键值。

JSON 数组  

为了节省空间,JSON 文件有时会以数组而非对象的形式编码。在这种情况下,处理的是 JSON 数组列表:

cat arrays.json
["Akiba_Hebrew_Academy", "2017-08-01", 241],["Aegithina_tiphia", "2018-02-01", 34],["1971-72_Utah_Stars_season", "2016-10-01", 1]

ClickHouse 会按数组值的顺序映射到列,使用 JSONCompactEachRow 格式加载此类数据:

SELECT * FROM sometable
┌─c1────────────────────────┬─────────c2─┬──c3─┐│ Akiba_Hebrew_Academy      │ 2017-08-01 │ 241 ││ Aegithina_tiphia          │ 2018-02-01 │  34 ││ 1971-72_Utah_Stars_season │ 2016-10-01 │   1 │└───────────────────────────┴────────────┴─────┘

从 JSON 数组中导入单独的列  

在某些情况下,数据按列而非按行编码,此时父 JSON 对象包含列及其值。以下是一个示例文件:

cat columns.json
{  "path": ["2007_Copa_America", "Car_dealerships_in_the_USA", "Dihydromyricetin_reductase"],  "month": ["2016-07-01", "2015-07-01", "2015-07-01"],  "hits": [178, 11, 1]}

ClickHouse 使用 JSONColumns 格式解析此类数据:

SELECT * FROM file('columns.json', JSONColumns)
┌─path───────────────────────┬──────month─┬─hits─┐│ 2007_Copa_America          │ 2016-07-01 │  178 ││ Car_dealerships_in_the_USA │ 2015-07-01 │   11 ││ Dihydromyricetin_reductase │ 2015-07-01 │    1 │└────────────────────────────┴────────────┴──────┘

对于列数组而非对象的场景,还可以使用更紧凑的 JSONCompactColumns 格式:

SELECT * FROM file('columns-array.json', JSONCompactColumns)
┌─c1──────────────┬─────────c2─┬─c3─┐│ Heidenrod       │ 2017-01-01 │ 10 ││ Arthur_Henrique │ 2016-11-01 │ 12 ││ Alan_Ebnother   │ 2015-11-01 │ 66 │└─────────────────┴────────────┴────┘

将 JSON 对象保存为字符串而不解析  

在处理结构不同的 JSON 列表时,您可能希望将 JSON 对象以字符串形式保存,而不对其进行解析。例如,以下是一个包含多个不同结构 JSON 对象的父列表:

cat custom.json
[  {"name": "Joe", "age": 99, "type": "person"},  {"url": "/my.post.MD", "hits": 1263, "type": "post"},  {"message": "Warning on disk usage", "type": "log"}]

可以将原始 JSON 对象存储到以下表结构中:

CREATE TABLE events(    `data` String)ENGINE = MergeTreeORDER BY ()

通过使用 JSONAsString 格式,可以将文件中的数据加载到表中,并保留 JSON 对象的原始格式而不进行解析:

INSERT INTO events (data)FROM INFILE 'custom.json'FORMAT JSONAsString

同时,可以使用 JSON 函数查询已保存的对象:

SELECT    JSONExtractString(data, 'type') AS type,    dataFROM events
┌─type───┬─data─────────────────────────────────────────────────┐│ person │ {"name": "Joe", "age": 99, "type": "person"}         ││ post   │ {"url": "/my.post.MD", "hits": 1263, "type": "post"} ││ log    │ {"message": "Warning on disk usage", "type": "log"}  │└────────┴──────────────────────────────────────────────────────┘

需要注意,JSONAsString 格式同样适用于每行包含一个 JSON 对象的文件(通常使用 JSONEachRow 格式)。

嵌套对象的架构  

处理嵌套 JSON 对象时,可定义复杂类型的架构(如 Array、Object 数据类型或 Tuple)以加载数据:

SELECT *FROM file('list-nested.json', JSONEachRow, 'page Tuple(path String, title String, owner_id UInt16), month Date, hits UInt32')LIMIT 1
┌─page───────────────────────────────────────────────┬──────month─┬─hits─┐│ ('Akiba_Hebrew_Academy','Akiba Hebrew Academy',12) │ 2017-08-01 │  241 │└────────────────────────────────────────────────────┴────────────┴──────┘

访问嵌套 JSON 对象  

我们可以通过启用以下设置选项来引用嵌套的 JSON 键:

SET input_format_import_nested_json = 1

这使得我们可以使用点表示法来引用嵌套的 JSON 键(需使用反引号括起来):

SELECT *FROM file('list-nested.json', JSONEachRow, '`page.owner_id` UInt32, `page.title` String, month Date, hits UInt32')LIMIT 1
┌─page.owner_id─┬─page.title───────────┬──────month─┬─hits─┐│            12 │ Akiba Hebrew Academy │ 2017-08-01 │  241 │└───────────────┴──────────────────────┴────────────┴──────┘

这种方式允许将嵌套的 JSON 对象展平,或提取部分嵌套值作为单独的列保存。

跳过未知列的行为  

默认情况下,ClickHouse 在导入 JSON 数据时会跳过未知列。例如,尝试将一个缺少 month 列的表导入原始文件:

CREATE TABLE shorttable(    `path` String,    `hits` UInt32)ENGINE = MergeTreeORDER BY path

即使原始 JSON 数据包含 3 列,仍可成功插入表中:

INSERT INTO shorttable FROM INFILE 'list.json' FORMAT JSONEachRow;SELECT * FROM shorttable
┌─path──────────────────────┬─hits─┐│ 1971-72_Utah_Stars_season │    1 ││ Aegithina_tiphia          │   34 ││ Akiba_Hebrew_Academy      │  241 │└───────────────────────────┴──────┘

导入过程中,未知列会被自动忽略。若希望禁用该行为,可以设置 input_format_skip_unknown_fields 选项:

SET input_format_skip_unknown_fields = 0;INSERT INTO shorttable FROM INFILE 'list.json' FORMAT JSONEachRow;
Ok.Exception on client:Code: 117. DB::Exception: Unknown field found while parsing JSONEachRow format: month: (in file/uri /data/clickhouse/user_files/list.json): (at row 1)

当 JSON 数据与表列结构不匹配时,ClickHouse 将抛出异常。

BSON 文件的导入与导出  

ClickHouse 支持 BSON 文件的数据导入与导出,这是一种被 MongoDB 等数据库管理系统广泛使用的格式。

要导入 BSON 数据,可使用 BSONEachRow 格式。以下示例展示了从 BSON 文件导入数据的过程:

SELECT * FROM file('data.bson', BSONEachRow)
┌─path──────────────────────┬─month─┬─hits─┐│ Bob_Dolman                │ 17106 │  245 ││ 1-krona                   │ 17167 │    4 ││ Ahmadabad-e_Kalij-e_Sofla │ 17167 │    3 │└───────────────────────────┴───────┴──────┘

同样,可以使用相同的格式将数据导出为 BSON 文件:

SELECT *FROM sometableINTO OUTFILE 'out.bson'FORMAT BSONEachRow

数据导出成功后,将存储于 out.bson 文件中。

Image

ClickHouse 中的其他 JSON 建模方法  

以下是 ClickHouse 中建模 JSON 的一些替代方案。这些方法主要是为了完整性记录,但通常不推荐使用,且不适用于大多数场景。

使用 Nested  

Nested 类型适用于建模静态且变化较少的对象,是 Tuple 和 Array(Tuple) 的替代方案。尽管如此,我们通常不建议在 JSON 数据中使用 Nested 类型,因为它的行为可能令人困惑。但 Nested 的一个显著优势是其子列可以用作排序键。

以下示例展示了使用 Nested 类型建模静态对象的方式。以下是一个简单的 JSON 日志条目:

{  "timestamp": 897819077,  "clientip": "45.212.12.0",  "request": {    "method": "GET",    "path": "/french/images/hm_nav_bar.gif",    "version": "HTTP/1.0"  },  "status": 200,  "size": 3305}``
We can declare the `request` key as `Nested`. Similar to `Tuple`, we are required to specify the sub columns.
```sql-- defaultSET flatten_nested=1CREATE table http( timestamp Int32, clientip IPv4, request Nested(method LowCardinality(String), path String, version LowCardinality(String)), status UInt16, size UInt32,) ENGINE = MergeTree() ORDER BY (status, timestamp);

flatten_nested 设置  

flatten_nested 控制 Nested 的行为,有两种主要模式:

flatten_nested=1  

当设置为 1(默认值)时,不支持任意级别的嵌套。此时,可将嵌套数据视为多个长度相同的 Array 列。字段 method、path 和 version 会作为独立的 Array 列,但其长度必须相同:

SHOW CREATE TABLE http
CREATE TABLE http( `timestamp` Int32, `clientip` IPv4, `request.method` Array(LowCardinality(String)), `request.path` Array(String), `request.version` Array(LowCardinality(String)), `status` UInt16, `size` UInt32)ENGINE = MergeTreeORDER BY (status, timestamp)

我们可以向表中插入数据,

SET input_format_import_nested_json = 1;INSERT INTO httpFORMAT JSONEachRow{"timestamp":897819077,"clientip":"45.212.12.0","request":[{"method":"GET","path":"/french/images/hm_nav_bar.gif","version":"HTTP/1.0"}],"status":200,"size":3305}

这里有几个需要注意的点:

1. 启用 input_format_import_nested_json 设置,才能以嵌套结构插入 JSON。未启用时,需展平 JSON:  

INSERT INTO http FORMAT JSONEachRow{"timestamp":897819077,"clientip":"45.212.12.0","request":{"method":["GET"],"path":["/french/images/hm_nav_bar.gif"],"version":["HTTP/1.0"]},"status":200,"size":3305}

2. 嵌套字段 method、path 和 version 必须以 JSON 数组的形式传递:  

{  "@timestamp": 897819077,  "clientip": "45.212.12.0",  "request": {    "method": [      "GET"    ],    "path": [      "/french/images/hm_nav_bar.gif"    ],    "version": [      "HTTP/1.0"    ]  },  "status": 200,  "size": 3305}

3. 可以使用点符号访问嵌套列:

SELECT clientip, status, size, `request.method` FROM http WHERE has(request.method, 'GET');
┌─clientip────┬─status─┬─size─┬─request.method─┐│ 45.212.12.0 │ 200 │ 3305 │ ['GET'] │└─────────────┴────────┴──────┴────────────────┘1 row in set. Elapsed: 0.002 sec.

由于子列为 Array 类型,可以使用完整的 Array 函数集,包括 ARRAY JOIN 子句——当列包含多个值时,这非常实用。

flatten_nested=0  

当设置为 0 时,允许任意嵌套级别。嵌套列被视为元组数组,与 Array(Tuple) 等效:

这是推荐的 Nested 使用方式,只需将嵌套对象表示为列表即可:

注意以下几点:

CREATE TABLE http(    `timestamp` Int32,    `clientip` IPv4,    `request` Nested(method LowCardinality(String), path String, version LowCardinality(String)),    `status` UInt16,    `size` UInt32)ENGINE = MergeTreeORDER BY (status, timestamp)
SHOW CREATE TABLE http
-- note Nested type is preserved.CREATE TABLE default.http( `timestamp` Int32, `clientip` IPv4, `request` Nested(method LowCardinality(String), path String, version LowCardinality(String)), `status` UInt16, `size` UInt32)ENGINE = MergeTreeORDER BY (status, timestamp)
INSERT INTO httpFORMAT JSONEachRow{"timestamp":897819077,"clientip":"45.212.12.0","request":[{"method":"GET","path":"/french/images/hm_nav_bar.gif","version":"HTTP/1.0"}],"status":200,"size":3305}

1. 无需启用 input_format_import_nested_json 设置。  

2. Nested 类型在 SHOW CREATE TABLE 中显示为 Array(Tuple)。  

3. 插入时需要将嵌套对象作为数组处理:  

{  "timestamp": 897819077,  "clientip": "45.212.12.0",  "request": [    {      "method": "GET",      "path": "/french/images/hm_nav_bar.gif",      "version": "HTTP/1.0"    }  ],  "status": 200,  "size": 3305}

列同样可以通过点符号再次访问:

SELECT clientip, status, size, `request.method` FROM http WHERE has(request.method, 'GET');
┌─clientip────┬─status─┬─size─┬─request.method─┐│ 45.212.12.0 │ 200 │ 3305 │ ['GET'] │└─────────────┴────────┴──────┴────────────────┘1 row in set. Elapsed: 0.002 sec.

示例 

上述数据的更大示例可以在 s3 的公共存储桶中获取,路径为:s3://datasets-documentation/http/。

SELECT *FROM s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/http/documents-01.ndjson.gz', 'JSONEachRow')LIMIT 1FORMAT PrettyJSONEachRow
{ "@timestamp": "893964617", "clientip": "40.135.0.0", "request": { "method": "GET", "path": "\/images\/hm_bg.jpg", "version": "HTTP\/1.0" }, "status": "200", "size": "24736"}
1 row in set. Elapsed: 0.312 sec.

基于 JSON 的限制和输入格式,我们通过以下查询插入此示例数据集,并将 flatten_nested 设置为 0:

以下语句将插入 1000 万行数据,可能需要几分钟执行。如有必要,可以通过 LIMIT 限制行数:
INSERT INTO httpSELECT `@timestamp` AS `timestamp`, clientip, [request], status,size FROM s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/http/documents-01.ndjson.gz','JSONEachRow');

查询这些数据时,需要以数组的形式访问 request 字段。以下是我们对固定时间段内的错误和 HTTP 方法的汇总结果:  

SELECT status, request.method[1] as method, count() as cFROM httpWHERE status >= 400  AND toDateTime(timestamp) BETWEEN '1998-01-01 00:00:00' AND '1998-06-01 00:00:00'GROUP by method, statusORDER BY c DESC LIMIT 5;
┌─status─┬─method─┬─────c─┐│ 404 │ GET │ 11267 ││ 404 │ HEAD │ 276 ││ 500 │ GET │ 160 ││ 500 │ POST │ 115 ││ 400 │ GET │ 81 │└────────┴────────┴───────┘
5 rows in set. Elapsed: 0.007 sec.

使用成对数组(Pairwise Arrays)  

成对数组是一种在 JSON 灵活性与性能之间的折中方法。其优点是可以在根级别动态添加新字段,但其查询语法较为复杂,且不支持嵌套结构。

以下为一个成对数组表的示例:

CREATE TABLE http_with_arrays (   keys Array(String),   values Array(String))ENGINE = MergeTree  ORDER BY tuple();

要插入数据,需要将 JSON 构造为键值对列表,并使用 JSONExtractKeysAndValues 函数完成:

SELECT    arrayMap(x -> (x.1), JSONExtractKeysAndValues(json, 'String')) AS keys,    arrayMap(x -> (x.2), JSONExtractKeysAndValues(json, 'String')) AS valuesFROM s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/http/documents-01.ndjson.gz', 'JSONAsString')LIMIT 1FORMAT Vertical
Row 1:──────keys: ['@timestamp','clientip','request','status','size']values: ['893964617','40.135.0.0','{"method":"GET","path":"/images/hm_bg.jpg","version":"HTTP/1.0"}','200','24736']
1 row in set. Elapsed: 0.416 sec.

请注意,request 列依然是一个嵌套结构,存储为字符串。我们可以向根级别添加新的键值,同时 JSON 本身也允许插入任意差异。要将数据插入本地表,请执行以下操作:

INSERT INTO http_with_arraysSELECT    arrayMap(x -> (x.1), JSONExtractKeysAndValues(json, 'String')) AS keys,    arrayMap(x -> (x.2), JSONExtractKeysAndValues(json, 'String')) AS valuesFROM s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/http/documents-01.ndjson.gz', 'JSONAsString')
0 rows in set. Elapsed: 12.121 sec. Processed 10.00 million rows, 107.30 MB (825.01 thousand rows/s., 8.85 MB/s.)

查询此结构需要结合 indexOf 函数,通过键名获取值数组对应的索引。例如:values[indexOf(keys, 'status')]。对于嵌套 JSON,例如 request 列,可结合 simpleJSONExtractString 提取值。

SELECT toUInt16(values[indexOf(keys, 'status')])                           as status,       simpleJSONExtractString(values[indexOf(keys, 'request')], 'method') as method,       count()                                                             as cFROM http_with_arraysWHERE status >= 400  AND toDateTime(values[indexOf(keys, '@timestamp')]) BETWEEN '1998-01-01 00:00:00' AND '1998-06-01 00:00:00'GROUP by method, status ORDER BY c DESC LIMIT 5;
┌─status─┬─method─┬─────c─┐│ 404 │ GET │ 11267 ││ 404 │ HEAD │ 276 ││ 500 │ GET │ 160 ││ 500 │ POST │ 115 ││ 400 │ GET │ 81 │└────────┴────────┴───────┘
5 rows in set. Elapsed: 0.383 sec. Processed 8.22 million rows, 1.97 GB (21.45 million rows/s., 5.15 GB/s.)Peak memory usage: 51.35 MiB.

/END/

ImageImage注册ClickHouse中国社区大使,领取认证考试券

Image

ClickHouse社区大使计划正式启动,首批过审贡献者享原厂认证考试券!

试用阿里云 ClickHouse企业版

轻松节省30%云资源成本?阿里云数据库ClickHouse 云原生架构全新升级,首次购买ClickHouse企业版计算和存储资源组合,首月消费不超过99.58元(包含最大16CCU+450G OSS用量)了解详情:https://t.aliyun.com/Kz5Z0q9G

Image

Image

征稿启示

面向社区长期正文,文章内容包括但不限于关于 ClickHouse 的技术研究、项目实践和创新做法等。建议行文风格干货输出&图文并茂。质量合格的文章将会发布在本公众号,优秀者也有机会推荐到 ClickHouse 官网。请将文章稿件的 WORD 版本发邮件至:[email protected]

ImageImage