如何实现ClickHouse在单表亿级记录上快速分组查询,秒杀其他OLAP数据库?

2026-05-27 13:451阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计792个文字,预计阅读时间需要4分钟。

如何实现ClickHouse在单表亿级记录上快速分组查询,秒杀其他OLAP数据库?

1. 启动并下载clickhouse-server,默认情况下,启动的服务器实例将作为默认用户运行,无需密码。使用以下命令: docker run -d --name ch-server --ulimit nofile=262144:262144 -p 8123:8123 -p 9000:9000 -p 9009:9009

1. 启动并下载一个clickhouse-server,By default, starting above server instance will be run as default user without password.

docker run -d --name ch-server --ulimit nofile=262144:262144 -p 8123:8123 -p 9000:9000 -p 9009:9009 yandex/clickhouse-server
或者加一个Mount
docker run -d --name ch-server --ulimit nofile=262144:262144 -p 8123:8123 -p 9000:9000 -p 9009:9009 -v e:\\taobao:/usr/src/app/ yandex/clickhouse-server

2. 打开浏览器, 输入, 查询结果就下载下来

localhost:8123/?query=SELECT%20%27Hello,%20ClickHouse!%27

3. 进入docker 的CLI, server端安装在/etc/clickhouse-server 目录 用clickhouse-client来执行客户端命令

4. 通过csv导入数据, 把本地目录Mount 到/usr/src/app目录

如何实现ClickHouse在单表亿级记录上快速分组查询,秒杀其他OLAP数据库?

clickhouse-client --query='INSERT INTO tblSale FORMAT CSV' < /usr/src/app/tblsale_in.csv

csv必须是逗号分隔,而且DateTime格式必须是不带毫秒的, 不然会有下面的错误

clickhouse-client --query='INSERT INTO tblSale FORMAT CSV' < /usr/src/app/tblsale_in.csv# Code: 117. DB::Exception: Expected end of line: (at row 1) Row 1: Column 0, name: id, type: UInt32, parsed text: "1" Column 1, name: prod_id, type: UInt32, parsed text: "1" Column 2, name: user_id, type: UInt32, parsed text: "1" Column 3, name: cnt, type: UInt32, parsed text: "1" Column 4, name: total_price, type: Float32, parsed text: "1.00" Column 5, name: date, type: DateTime, parsed text: "2022-04-22 17:56:00" ERROR: garbage after DateTime: ".783<CARRIAGE RETURN><LINE FEED>2,2," ERROR: DateTime must be in YYYY-MM-DD hh:mm:ss or NNNNNNNNNN (unix timestamp, exactly 10 digits) format. : While executing CSVRowInputFormat: data for INSERT was parsed from stdin: (in query: INSERT INTO tblSale FORMAT CSV). (INCORRECT_DATA)

我的数据是从SQLServer导出的, 可以用BCP导出指定逗号分隔

bcp "SELECT [id],[prod_id],[user_id] ,[cnt],[total_price],Convert(varchar(20) , date, 120) as date FROM [taobao].[dbo].[tblSale_in]" queryout tblSale_in.csv -c -t , -T -S .\SQLExpress

当我导入的csv数据量很少时, 很快就成功了, 我再用有200w条数据时的csv, 执行这条命令是感觉就没有反应了.新打开一个CLI,进入clickhouse-client 也没有反应了,不知道是否死掉了

等待5分种后,出现这个错误,

Code: 209. DB::NetException: Timeout exceeded while reading from socket (127.0.0.1:9000, 300000 ms). (SOCKET_TIMEOUT)

但是第2天再导入的时候就算导入2000w数据也很快, 在1分钟以内, 不知道什么原因

=========================以下是ClickHouse和SQLServer 2012的性能对比=====================================

硬件: THINKPAD470, I5CPU,8G内存,机械硬盘

--统计每日销量,2000w数据 SQLServer 17秒 SELECT Convert(varchar(8) , date, 112) as date,count(*) as dayCnt FROM [taobao].[dbo].[tblSale] group by Convert(varchar(8) , date, 112) order by Convert(varchar(8) , date, 112)

--按日统计数量, ClickHouse 2500w数据第一次用时8.35秒,第二次用时0.3秒 SELECT toYYYYMMDD(date), count(*) as dayCnt FROM tblSale group by toYYYYMMDD(date) order by toYYYYMMDD(date)

继续导入2000w数据, 再用上面的SQL, clickhouse 4500w数据用时0.58秒, 6000w数据用时0.5秒 (第一次查询用1.24秒), 8000w数据用时0.68秒,1亿数据用时0.95秒

ClickHouse Join 数据是把右边的表全部Load到内存里(看你的内存给不给力哦),所以第一次查询时很慢, 但第2次之后就很快.

重启docker之后查询也是第一次很慢,说明它的缓存是在内存里,而不是磁盘

=================== 结论==================================

对于一般OLAP应用, 比如查用户的历史记录, 不要去搞分库分表, 那是条歪路,还是转到列数据库, 搞个大宽表, 尽量不要用Join, 单机都能达到这么高的性能.

本文共计792个文字,预计阅读时间需要4分钟。

如何实现ClickHouse在单表亿级记录上快速分组查询,秒杀其他OLAP数据库?

1. 启动并下载clickhouse-server,默认情况下,启动的服务器实例将作为默认用户运行,无需密码。使用以下命令: docker run -d --name ch-server --ulimit nofile=262144:262144 -p 8123:8123 -p 9000:9000 -p 9009:9009

1. 启动并下载一个clickhouse-server,By default, starting above server instance will be run as default user without password.

docker run -d --name ch-server --ulimit nofile=262144:262144 -p 8123:8123 -p 9000:9000 -p 9009:9009 yandex/clickhouse-server
或者加一个Mount
docker run -d --name ch-server --ulimit nofile=262144:262144 -p 8123:8123 -p 9000:9000 -p 9009:9009 -v e:\\taobao:/usr/src/app/ yandex/clickhouse-server

2. 打开浏览器, 输入, 查询结果就下载下来

localhost:8123/?query=SELECT%20%27Hello,%20ClickHouse!%27

3. 进入docker 的CLI, server端安装在/etc/clickhouse-server 目录 用clickhouse-client来执行客户端命令

4. 通过csv导入数据, 把本地目录Mount 到/usr/src/app目录

如何实现ClickHouse在单表亿级记录上快速分组查询,秒杀其他OLAP数据库?

clickhouse-client --query='INSERT INTO tblSale FORMAT CSV' < /usr/src/app/tblsale_in.csv

csv必须是逗号分隔,而且DateTime格式必须是不带毫秒的, 不然会有下面的错误

clickhouse-client --query='INSERT INTO tblSale FORMAT CSV' < /usr/src/app/tblsale_in.csv# Code: 117. DB::Exception: Expected end of line: (at row 1) Row 1: Column 0, name: id, type: UInt32, parsed text: "1" Column 1, name: prod_id, type: UInt32, parsed text: "1" Column 2, name: user_id, type: UInt32, parsed text: "1" Column 3, name: cnt, type: UInt32, parsed text: "1" Column 4, name: total_price, type: Float32, parsed text: "1.00" Column 5, name: date, type: DateTime, parsed text: "2022-04-22 17:56:00" ERROR: garbage after DateTime: ".783<CARRIAGE RETURN><LINE FEED>2,2," ERROR: DateTime must be in YYYY-MM-DD hh:mm:ss or NNNNNNNNNN (unix timestamp, exactly 10 digits) format. : While executing CSVRowInputFormat: data for INSERT was parsed from stdin: (in query: INSERT INTO tblSale FORMAT CSV). (INCORRECT_DATA)

我的数据是从SQLServer导出的, 可以用BCP导出指定逗号分隔

bcp "SELECT [id],[prod_id],[user_id] ,[cnt],[total_price],Convert(varchar(20) , date, 120) as date FROM [taobao].[dbo].[tblSale_in]" queryout tblSale_in.csv -c -t , -T -S .\SQLExpress

当我导入的csv数据量很少时, 很快就成功了, 我再用有200w条数据时的csv, 执行这条命令是感觉就没有反应了.新打开一个CLI,进入clickhouse-client 也没有反应了,不知道是否死掉了

等待5分种后,出现这个错误,

Code: 209. DB::NetException: Timeout exceeded while reading from socket (127.0.0.1:9000, 300000 ms). (SOCKET_TIMEOUT)

但是第2天再导入的时候就算导入2000w数据也很快, 在1分钟以内, 不知道什么原因

=========================以下是ClickHouse和SQLServer 2012的性能对比=====================================

硬件: THINKPAD470, I5CPU,8G内存,机械硬盘

--统计每日销量,2000w数据 SQLServer 17秒 SELECT Convert(varchar(8) , date, 112) as date,count(*) as dayCnt FROM [taobao].[dbo].[tblSale] group by Convert(varchar(8) , date, 112) order by Convert(varchar(8) , date, 112)

--按日统计数量, ClickHouse 2500w数据第一次用时8.35秒,第二次用时0.3秒 SELECT toYYYYMMDD(date), count(*) as dayCnt FROM tblSale group by toYYYYMMDD(date) order by toYYYYMMDD(date)

继续导入2000w数据, 再用上面的SQL, clickhouse 4500w数据用时0.58秒, 6000w数据用时0.5秒 (第一次查询用1.24秒), 8000w数据用时0.68秒,1亿数据用时0.95秒

ClickHouse Join 数据是把右边的表全部Load到内存里(看你的内存给不给力哦),所以第一次查询时很慢, 但第2次之后就很快.

重启docker之后查询也是第一次很慢,说明它的缓存是在内存里,而不是磁盘

=================== 结论==================================

对于一般OLAP应用, 比如查用户的历史记录, 不要去搞分库分表, 那是条歪路,还是转到列数据库, 搞个大宽表, 尽量不要用Join, 单机都能达到这么高的性能.