跳至主要内容

·阅读时间:1分钟

当用户级设置在错误的位置指定时,服务器将无法启动,并且会将异常消息发送到日志。但是,您可以告诉 ClickHouse 使用 skip_check_for_incorrect_settings 设置忽略不正确的设置

将以下内容添加到 config.xml

<skip_check_for_incorrect_settings>1</skip_check_for_incorrect_settings>
注意

用户级设置应在 users.xml 中的特定用户配置文件的 <profile> 部分中指定(或在 <default> 中用于默认设置)。

·阅读时间:1分钟

客户端可以查看服务器日志——即使在与服务器日志级别配置不同的级别上——通过设置 send_logs_level 客户端设置。

例如,假设客户端运行

SET send_logs_level = 'trace';

即使服务器的日志级别设置为 info,客户端也会收到跟踪日志。

一个有用的场景是使用 send_logs_level 监视插入 Distributed 表中的行

  • 使用 SET send_logs_level = 'trace';clickhouse-client 中启用日志
  • 运行您的 INSERT 查询
  • 默认情况下,插入分布式表是异步的。数据写入磁盘上的本地缓冲区,然后在后台发送到远程服务器。
  • 日志将从参与查询处理的所有节点发送(分布式跟踪)

要检查分布式插入的状态,请检查 system.distribution_queue。此表包含有关队列中要发送到分片的本地文件的信息。这些本地文件包含通过异步模式将新数据插入 Distributed 表而创建的新部分。

·阅读时间:2分钟

要比较两个查询之间的指标,您必须首先获取两个查询的 query_id

然后,您可以运行以下查询

WITH
initial_query_id = '82142964-0b5d-4263-b996-302ce14bd779' AS second,
initial_query_id = '7ea39e31-2f89-4085-843c-7246cb3baa5c' AS first
SELECT
PE.1 AS metric,
sumIf(PE.2, first) AS v1,
sumIf(PE.2, second) AS v2,
10 * log10(v2 / v1) AS dB
FROM clusterAllReplicas(
default, system.query_log)
ARRAY JOIN ProfileEvents AS PE
WHERE (first OR second)
AND (event_date >= today() - 3) AND (type = 2)
GROUP BY metric
HAVING v1 != v2
ORDER BY
dB DESC,
v2 DESC,
metric ASC FORMAT PrettyCompactMonoBlock

您将收到一个包含比较两个查询的指标的表

Query id: d7747d26-a231-47c8-ae8c-284895b1aeaf

┌─metric──────────────────────────────────────┬─────────v1─┬─────────v2─┬───────────────────────dB─┐
│ SystemTimeMicroseconds │ 13812127240819382.4143087099482767
│ SoftPageFaults │ 265188740568891.846381108610876
│ DiskReadElapsedMicroseconds │ 111394712737860.582319430863304
│ CachedReadBufferReadFromCacheMicroseconds │ 112650512854500.57322064922068
│ OSCPUVirtualTimeMicroseconds │ 70301588800453770.5637111926869545
│ RealTimeMicroseconds │ 86686457963394710.4585300419916516
│ QueryProfilerRuns │ 1571740.4464959587336597
│ NetworkSendBytes │ 8681979408590.349062627796429
│ NetworkReceiveElapsedMicroseconds │ 1611740.3372337225075003
│ ArenaAllocBytes │ 148058931214973665280.04893510724370622
│ OSWriteBytes │ 3809283850240.04644905045763538
│ ArenaAllocChunks │ 215321570.00806115279057892
│ FileOpen │ 751175160.0028900944828012766
│ OpenedFileCacheMisses │ 751175160.0028900944828012766
│ ContextLock │ 588058810.0007385332589917156
│ OSReadChars │ 23407914322340789818-0.000002994506583727971
│ OSWriteChars │ 25213102513992-0.012623549714419216
│ AggregationPreallocatedElementsInHashTables │ 128039910127563540-0.016187974135432794
│ OSCPUWaitMicroseconds │ 15436431536999-0.018732829140838268
│ OpenedFileCacheHits │ 539534-0.040475081581823065
│ UserTimeMicroseconds │ 5649084055961729-0.04086908559606555
│ WaitMarksLoadMicroseconds │ 388571359985-0.3318598023153847
│ ThreadpoolReaderTaskMicroseconds │ 38166693392522-0.5116182478775457
│ NetworkSendElapsedMicroseconds │ 47454122-0.6112822932011739
│ AsynchronousReadWaitMicroseconds │ 23802842025078-0.7018702173136342
│ NetworkReceiveBytes │ 516372-1.4210676174531387
└─────────────────────────────────────────────┴────────────┴────────────┴──────────────────────────┘

26 rows in set. Elapsed: 0.173 sec. Processed 5.86 million rows, 2.40 GB (33.92 million rows/s., 13.92 GB/s.)

·阅读时间:1分钟

价格

有关定价信息,请参阅 ClickHouse 云定价 页面。要了解哪些因素会影响您的账单以及管理支出的方法,请继续阅读。

Amazon Web Services(AWS) 示例

注意

价格反映了 AWS us-east-1 的定价。

开发:每月 51 美元起

最适合:入门项目和暂存

  • 开发服务
  • 16 GiB RAM,2 个 vCPU
  • 1 TB 数据

此示例的定价细分:

10% 活动50% 活动始终开启
计算$16$79$158
存储$35$35$35
总计$51$114$193
注意

如果使用的磁盘小于 1TB,则消耗量甚至更低

生产(空闲,自动扩展):每月 172 美元起

最适合:对成本敏感的临时分析应用程序

  • 生产服务
  • 活动工作负载约占 25% 的时间
  • 使用默认设置处于空闲状态
  • 自动扩展最大值设置为防止账单失控

此示例的定价细分:

示例 1示例 2示例 3
计算24 GiB RAM,6 个 vCPU
$125
192 GiB RAM,48 个 vCPU
$1000
720 GiB RAM,180 个 vCPU
$3750
存储1 TB 数据
$47
5 TB 数据
$235
10 TB 数据
$470
总计$172$1,235$4,220

生产(始终在线,预留容量):每月 550 美元起

最适合:延迟敏感型应用程序

  • 生产服务
  • 活动工作负载 ~100% 时间
  • 自动扩展最小值设置为预留容量

此示例的定价细分:

示例 1示例 2示例 3
计算24 GiB RAM,6 个 vCPU
$503
96 GiB RAM,24 个 vCPU
$2,012
360 GiB RAM,90 个 vCPU
$7,545
存储1 TB 数据
$47
4 TB 数据
$188
8 TB 数据
$376
总计$550$2,200$7,921

如果您已经是 ClickHouse Cloud 用户,请咨询 支持 获取更多估算帮助,否则请联系 [email protected]

Google Cloud Platform (GCP) 示例

注意

价格反映了 GCP us-central-1 的定价。

开发:每月 46 美元起

最适合:入门项目和暂存

  • 开发服务
  • 16 GiB RAM,2 个 vCPU
  • 1 TB 数据

此示例的定价细分:

10% 活动50% 活动始终开启
计算$15$74$147
存储$31$31$31
总计$46$105$178
注意

如果使用的磁盘小于 1TB,则消耗量甚至更低

生产(空闲,自动扩展):每月 146 美元起

最适合:对成本敏感的临时分析应用程序

  • 生产服务
  • 活动工作负载约占 25% 的时间
  • 使用默认设置处于空闲状态
  • 自动扩展最大值设置为防止账单失控

此示例的定价细分:

示例 1示例 2示例 3
计算24 GiB RAM,6 个 vCPU
$105
192 GiB RAM,48 个 vCPU
$843
720 GiB RAM,180 个 vCPU
$3162
存储1 TB 数据
$41
5 TB 数据
$205
10 TB 数据
$410
总计$146$1,048$3,572

生产(始终在线,预留容量):每月 463 美元起

最适合:延迟敏感型应用程序

  • 生产服务
  • 活动工作负载 ~100% 时间
  • 自动扩展最小值设置为预留容量

此示例的定价细分:

示例 1示例 2示例 3
计算24 GiB RAM,6 个 vCPU
$422
96 GiB RAM,24 个 vCPU
$1,686
360 GiB RAM,90 个 vCPU
$6,342
存储1 TB 数据
$41
4 TB 数据
$164
8 TB 数据
$328
总计$463$1,850$6,652

如果您已经是 ClickHouse Cloud 用户,请咨询 支持 获取更多估算帮助,否则请联系 [email protected]

常见问题

如何计量计算资源?

ClickHouse Cloud 以分钟为单位计量计算资源,以 8G RAM 为增量。

如何计算磁盘存储?

ClickHouse Cloud 使用云对象存储,并根据存储在 ClickHouse 表中的数据的压缩大小进行计量。

备份是否计入总存储量?

ClickHouse Cloud 为生产服务提供两个免费备份,为开发服务提供一个免费备份。备份不计入存储量。

如何估算压缩率?

数据集的压缩率差异可能很大。它取决于数据本身的可压缩性(高基数字段与低基数字段的数量)以及用户如何设置架构(例如,是否使用可选编解码器)。对于常见的分析数据类型,压缩率可能达到 10 倍,但也可能显著降低或提高。请参阅 优化 文档以获取指导,并参阅此 Uber 博客 以了解详细的日志记录用例示例。唯一切实可行的方法是将您的数据集导入 ClickHouse 并将数据集的大小与存储在 ClickHouse 中的大小进行比较。

您可以使用查询 SELECT formatReadableSize(total_bytes) FROM system.tables WHERE name = <您的表名>

如果我拥有自管理部署,ClickHouse 提供哪些工具来估算在云中运行服务的成本?

ClickHouse 查询日志捕获了可用于估算在 ClickHouse Cloud 中运行工作负载成本的 关键指标。有关从自管理迁移到 ClickHouse Cloud 的详细信息,请参阅 迁移文档,如果您有任何其他问题,请联系 ClickHouse Cloud 支持

ClickHouse Cloud 提供哪些计费选项?

ClickHouse Cloud 支持以下计费选项

  • 自助服务每月(以美元计价,通过信用卡)
  • 直销年度/多年(通过预付“ClickHouse 信用额度”,以美元计价,并提供其他付款方式)

计费周期多长?

计费遵循每月计费周期,开始日期为创建 ClickHouse Cloud 组织的日期。

ClickHouse Cloud 提供哪些控制措施来管理生产服务的成本?

  • 试用版和年度承诺客户将在消费达到特定阈值(50%、75% 和 90%)时收到自动电子邮件通知,以便用户采取措施。
  • ClickHouse Cloud 允许用户通过 高级扩展控制 设置计算资源的自动扩展最大限制,这是分析工作负载的重要成本因素。
  • 高级扩展控制 允许您设置内存限制,并可以选择控制在空闲期间暂停/空闲的行为。

ClickHouse Cloud 提供哪些控制措施来管理开发服务的成本?

  • 高级扩展控制 允许您控制在空闲期间暂停/空闲的行为。开发服务不支持调整内存分配。
  • 请注意,默认设置会在一段时间不活动后暂停服务。

如果我有多个服务,我会收到每个服务的单独发票还是合并发票?

对于给定组织中的所有服务,都会为一个计费周期生成合并发票。

如果我在试用期和信用额度到期前添加我的信用卡并升级,我是否会被收费?

当用户在 30 天试用期结束前从试用到付费转换,但仍有试用信用额度剩余时,我们在最初的 30 天试用期内继续从试用信用额度中扣除,然后收取信用卡费用。

如何跟踪我的支出?

ClickHouse Cloud 控制台包含一个使用情况显示,提供有关每个服务的计算和存储使用情况的详细信息。这可以用来了解按计量单位细分的成本细分。

如何访问我针对 ClickHouse Cloud 服务的 AWS Marketplace 订阅的发票?

所有 Marketplace 订阅都将由 AWS 计费和开具发票。您可以从 AWS 计费仪表板下载发票。

为什么使用情况报表上的日期与我的 AWS Marketplace 发票不匹配?

AWS Marketplace 计费遵循日历月周期,例如,对于 2022 年 12 月 1 日至 2023 年 1 月 1 日之间的使用情况,将在 2023 年 1 月 3 日至 5 日之间生成发票。

ClickHouse Cloud 使用情况报表遵循不同的计费周期,其中使用情况在从注册之日起 30 天内进行计量和报告。

如果这些日期不相同,则使用情况和发票日期将有所不同。由于使用情况报表按天跟踪给定服务的用量,因此用户可以依靠报表查看成本细分。

预付信用额度的使用是否有任何限制?

ClickHouse Cloud 预付费额度(无论是通过 ClickHouse 直接获得,还是通过云提供商的市场获得)只能用于合同条款规定的时间段。这意味着它们可以在接受日期或未来某个日期使用,不能用于任何先前的时间段。任何预付费额度未涵盖的超额费用必须通过信用卡支付或市场每月账单支付。

·阅读时间:1分钟

您可以通过 AWS、GCP 和 Azure 市场订阅 ClickHouse Cloud。这使您可以通过现有的云提供商账单支付 ClickHouse Cloud 费用。

您可以使用即付即用 (PAYG) 或与 ClickHouse Cloud 签订合同(通过市场)。账单将由云提供商处理,您将收到包含所有云服务的单一发票。

常见问题

如何验证我的组织是否已连接到市场账单?

在 ClickHouse Cloud 控制台中,导航到**账单**。您应该在**付款详情**部分看到市场名称和链接。

我是一个现有的 ClickHouse Cloud 用户。当我通过 AWS/GCP/Azure 市场订阅 ClickHouse Cloud 时会发生什么?

从云提供商市场注册 ClickHouse Cloud 是一个两步过程

  1. 您首先在云提供商的市场门户网站上“订阅”ClickHouse Cloud。订阅完成后,点击“立即支付”或“在提供商处管理”(取决于市场)。这将重定向到 ClickHouse Cloud。
  2. 在 Clickhouse Cloud 上,您可以注册新帐户或使用现有帐户登录。无论哪种方式,都会为您创建一个新的 ClickHouse Cloud 组织,该组织与您的市场账单相关联。

注意:您从任何先前 ClickHouse Cloud 注册获得的现有服务和组织将保留,并且不会连接到市场账单。ClickHouse Cloud 允许您使用同一个帐户管理多个组织,每个组织都有不同的账单。

您可以从 ClickHouse Cloud 控制台左下角的菜单中切换组织。

我是一个现有的 ClickHouse Cloud 用户。如果我想通过市场对我的现有服务进行计费,我应该怎么做?

在这种情况下,请联系ClickHouse Cloud 支持。您需要通过市场订阅 ClickHouse Cloud,我们可以切换组织与资源的关联,以便通过市场进行计费。

我作为市场用户订阅了 ClickHouse Cloud。如何取消订阅?

请注意,您可以简单地停止使用 ClickHouse Cloud 并删除所有现有的 ClickHouse Cloud 服务。即使订阅仍然有效,您也不会支付任何费用,因为 ClickHouse Cloud 没有任何定期费用。

如果您想取消订阅,请导航到云提供商控制台并在那里取消订阅续订。订阅结束后,所有现有服务都将停止,并会提示您添加信用卡。如果未添加任何卡,两周后所有现有服务都将被删除。

我作为市场用户订阅了 ClickHouse Cloud,然后取消了订阅。现在我想重新订阅,流程是什么?

在这种情况下,请照常订阅 ClickHouse Cloud(请参阅有关通过市场订阅 ClickHouse Cloud 的部分)。

  • 对于 AWS 市场,将创建一个新的 ClickHouse Cloud 组织并将其连接到市场。
  • 对于 GCP 市场,您的旧组织将被重新激活。

如果您在重新激活市场组织时遇到任何问题,请联系ClickHouse Cloud 支持

如何访问我针对 ClickHouse Cloud 服务的市场订阅的发票?

为什么使用情况报表上的日期与我的市场发票不匹配?

市场账单遵循日历月周期。例如,对于 12 月 1 日至 1 月 1 日之间的使用情况,将在 1 月 3 日至 1 月 5 日之间生成发票。

ClickHouse Cloud 使用情况报表遵循不同的账单周期,其中使用情况以 30 天为单位进行计量和报告,从注册之日开始。

如果这些日期不相同,则使用情况和发票日期将有所不同。由于使用情况报表按天跟踪给定服务的用量,因此用户可以依靠报表查看成本细分。

在哪里可以找到一般账单信息?

请参阅账单概述页面

·阅读时间:1分钟

这些权限错误的根本原因已确定,是由于新版本中对async_inserts的授权进行了更严格的检查。

要解决此问题,必须更新服务的授权才能使其正常工作。检查指示缺少授权的错误消息,并手动添加所需的授权。使用async_inserts的表的额外所需授权将是SELECTdictGet授权。

向受影响的表和字典添加必要的 GRANT

-- Add SELECT grant permissions
GRANT SELECT ON mydb.insertTable TO insert_role WITH GRANT OPTION

-- Add dictGet grant permissions
GRANT dictGet ON mydb.insertDictionary TO insert_role

要了解有关GRANT命令的更多信息,请参阅此页面

如果您无法执行此更改,请联系ClickHouse 支持寻求帮助。

·阅读时间:3 分钟

问题

地图查找(例如a['key'])使用线性复杂度(此处提及),效率可能低下。这是因为从表中选择具有特定键的值需要遍历 Map 列中所有行(N)中的所有键(~M),导致 ~MxN 次查找。

使用 Map 进行查找可能比使用字符串列慢 10 倍。以下实验还显示了冷查询的 ~10 倍减速,以及处理数据数量的多个数量级差异(7.21 MB 对 5.65 GB)。

-- create table with SpanNAme as String and ResourceAttributes as Map
DROP TABLE IF EXISTS tbl;
CREATE TABLE tbl (
`Timestamp` DateTime64(9) CODEC (Delta(8), ZSTD(1)),
`TraceId` String CODEC (ZSTD(1)),
`ServiceName` LowCardinality(String) CODEC (ZSTD(1)),
`Duration` UInt8 CODEC (ZSTD(1)), -- Int64
`SpanName` LowCardinality(String) CODEC (ZSTD(1)),
`ResourceAttributes` Map(LowCardinality(String), String) CODEC (ZSTD(1))
)
ENGINE = MergeTree
PARTITION BY toDate(Timestamp)
ORDER BY (ServiceName, SpanName, toUnixTimestamp(Timestamp), TraceId);

-- create UDF to generate random Map data for ResourceAttributes
DROP FUNCTION IF EXISTS genmap;
CREATE FUNCTION genmap AS (n) -> arrayMap (x-> (x::String, (x*rand32())::String), range(1, n));

-- check that genmap is working as intended
SELECT genmap(10)::Map(String, String);

-- insert 1M rows
INSERT INTO tbl
SELECT
now() - randUniform(1, 1000000.) as Timestamp,
randomPrintableASCII(2) as TraceId,
randomPrintableASCII(2) as ServiceName,
rand32() as Duration,
randomPrintableASCII(2) as SpanName,
genmap(rand64()%500)::Map(String, String) as ResourceAttributes
FROM numbers(1_000_000);

-- querying for SpanName is faster
-- [cold] 0 rows in set. Elapsed: 0.642 sec. Processed 1.00 million rows, 7.21 MB (1.56 million rows/s., 11.22 MB/s.)
-- [warm] 0 rows in set. Elapsed: 0.164 sec. Processed 1.00 million rows, 7.21 MB (6.10 million rows/s., 43.99 MB/s.)
SELECT
COUNT(*),
avg(Duration/1E6) as average,
quantile(0.95)(Duration/1E6) as p95,
quantile(0.99)(Duration/1E6) as p99,
SpanName
FROM tbl
GROUP BY SpanName ORDER BY 1 DESC LIMIT 50 FORMAT Null;

-- query for ResourceAttributes is slower
-- [cold] 0 rows in set. Elapsed: 6.432 sec. Processed 1.00 million rows, 5.65 GB (155.46 thousand rows/s., 879.07 MB/s.)
-- [warm] 0 rows in set. Elapsed: 5.935 sec. Processed 1.00 million rows, 5.65 GB (168.50 thousand rows/s., 952.81 MB/s.)
SELECT
COUNT(*),
avg(Duration/1E6) as average,
quantile(0.95)(Duration/1E6) as p95,
quantile(0.99)(Duration/1E6) as p99,
ResourceAttributes['1'] as hostname
FROM tbl
GROUP BY hostname ORDER BY 1 DESC LIMIT 50 FORMAT Null;

解决方案为了改进查询,我们可以添加另一列,其值默认为 Map 列中的特定键,然后将其物化以填充现有行的值。这样,我们在插入时提取并存储必要的值,从而加快查询时的查找速度。

-- solution is to add a column with value defaulting to a particular key in Map
ALTER TABLE tbl ADD COLUMN hostname LowCardinality(String) DEFAULT ResourceAttributes['1'];
ALTER TABLE tbl MATERIALIZE COLUMN hostname;

-- query for hostname (new column) is now faster
-- [cold] 0 rows in set. Elapsed: 2.215 sec. Processed 1.00 million rows, 21.67 MB (451.52 thousand rows/s., 9.78 MB/s.)
-- [warm] 0 rows in set. Elapsed: 0.541 sec. Processed 1.00 million rows, 21.67 MB (1.85 million rows/s., 40.04 MB/s.)
SELECT
COUNT(*),
avg(Duration/1E6) as average,
quantile(0.95)(Duration/1E6) as p95,
quantile(0.99)(Duration/1E6) as p99,
hostname
FROM tbl
GROUP BY hostname ORDER BY 1 DESC LIMIT 50 FORMAT Null;

-- drop cache to run query cold
SYSTEM DROP FILESYSTEM CACHE;

·阅读时间:2分钟

简短的回答是“是的”。ClickHouse 具有多种机制,允许通过删除旧数据来释放磁盘空间。每种机制都针对不同的场景。

TTL

ClickHouse 允许在某些条件发生时自动删除值。此条件配置为基于任何列的表达式,通常只是任何时间戳列的静态偏移量。

这种方法的主要优点是它不需要任何外部系统来触发,一旦配置了 TTL,数据删除就会在后台自动发生。

注意

TTL 还可以用于将数据不仅移动到/dev/null,还可以移动到不同的存储系统,例如从 SSD 移动到 HDD。

有关配置 TTL的更多详细信息。

DELETE FROM

DELETE FROM 允许在 ClickHouse 中运行标准 DELETE 查询。过滤器子句中目标行将被标记为已删除,并从将来的结果集中移除。行的清理异步进行。

注意

DELETE FROM 通常从版本 23.3 及更高版本开始可用。在旧版本中,它是实验性的,必须使用以下方法启用

SET allow_experimental_lightweight_delete = true;

ALTER DELETE

ALTER DELETE 使用异步批处理操作删除行。与 DELETE FROM 不同,在 ALTER DELETE 之后和批处理操作完成之前运行的查询将包含目标删除的行。有关更多详细信息,请参阅ALTER DELETE 文档。

可以发出ALTER DELETE以灵活地删除旧数据。如果您需要定期执行此操作,主要缺点是需要有一个外部系统来提交查询。由于即使只有一行要删除,突变也会重写完整的部分,因此也有一些性能方面的考虑。

这是使基于 ClickHouse 的系统符合GDPR 的最常见方法。

有关突变的更多详细信息。

DROP PARTITION

ALTER TABLE ... DROP PARTITION提供了一种经济高效的方式来删除整个分区。它并不那么灵活,需要在表创建时配置正确的分区方案,但仍然涵盖了大多数常见情况。与突变一样,需要从外部系统执行以供定期使用。

有关操作分区的更多详细信息。

TRUNCATE

从表中删除所有数据相当激进,但在某些情况下,这可能正是您需要的。

有关表截断的更多详细信息。

·阅读时间:2分钟

问题

如何判断是否使用了投影?

答案

  1. 创建示例数据库
CREATE database db1;
  1. 创建一个示例表,该表将使用 column1 作为主键
CREATE table db1.table1_projections
(
column1 Int32,
column2 Int32
)
engine = MergeTree()
order by column1;
  1. 添加投影for_column2以使用 column2 作为主键
ALTER table db1.table1_projections add projection for_column2
(
select *
order by column2
);
  1. 插入测试数据

*这将插入 100000 行,其中 column1 和 column2 中包含随机数

INSERT INTO db1.table1_projections
select
floor(randNormal(50, 5)) as column1,
floor(randUniform(1, 100)) as column2
from numbers(100000);
  1. 检查数据样本集
clickhouse-cloud :) SELECT * from db1.table1_projections limit 5;

SELECT *
FROM db1.table1_projections
LIMIT 5

Query id: d6940799-b507-4a5e-9843-df55ebe818ab

┌─column1─┬─column2─┐
│ 28 │ 41 │
│ 29 │ 12 │
│ 30 │ 73 │
│ 30 │ 75 │
│ 30 │ 70 │
└─────────┴─────────┘
  1. 测试它是否正在使用带有 column1 的原始表
clickhouse-cloud :) explain indexes = 1 
SELECT count() from db1.table1_projections where column1 > 50;

EXPLAIN indexes = 1
SELECT count()
FROM db1.table1_projections
WHERE column1 > 50

Query id: e04d5236-1a05-4f1f-9502-7e41986beb44

┌─explain────────────────────────────────────────────┐
│ Expression ((Projection + Before ORDER BY)) │
│ Aggregating │
│ Expression (Before GROUP BY) │
│ Filter (WHERE) │
│ ReadFromMergeTree (db1.table1_projections) │
│ Indexes: │
│ PrimaryKey │
│ Condition: true │
│ Parts: 1/1 │
│ Granules: 12/12 │
└────────────────────────────────────────────────────┘

*注意它正在从db1.table1_projections读取

  1. 通过在 where 子句中使用 column2 来测试从投影读取
clickhouse-cloud :) explain indexes = 1 
SELECT * from db1.table1_projections where column2 > 50;

EXPLAIN indexes = 1
SELECT *
FROM db1.table1_projections
WHERE column2 > 50

Query id: d2b20e01-93bf-4b60-a370-4aac7b454267

┌─explain─────────────────────────────────────┐
│ Expression ((Projection + Before ORDER BY)) │
│ Filter │
│ ReadFromMergeTree (for_column2) │
│ Indexes: │
│ PrimaryKey │
│ Keys: │
│ column2 │
│ Condition: (column2 in [51, +Inf)) │
│ Parts: 1/1 │
│ Granules: 6/12 │
└─────────────────────────────────────────────┘

*注意现在使用了for_column2投影。

更多信息

投影:https://clickhouse.ac.cn/docs/en/sql-reference/statements/alter/projection

数字表函数:https://clickhouse.ac.cn/docs/en/sql-reference/table-functions/numbers

生成随机数据的博客:https://clickhouse.ac.cn/blog/generating-random-test-distribution-data-for-clickhouse

·阅读时间:2分钟

我能否仅仅使用requests模块向ClickHouse服务器发送HTTP请求?

回答

可以,以下是一个示例代码。

import requests
import datetime

create_replace_stmt = 'CREATE OR REPLACE TABLE test_table (name String, age UInt8) Engine=MergeTree ORDER BY tuple();'
select_query = 'SELECT count() FROM test_table'
insert_query = 'INSERT INTO test_table SELECT * FROM generateRandom(\'name String, age UInt8\',1,1) LIMIT 300000000'

CH_URL = 'https://your_clickhouse_service_fqdn:8443'
CH_USER = 'default'
CH_PASSWORD = 'secret_pwd'

headers = {}
headers["X-ClickHouse-User"] = CH_USER
headers["X-ClickHouse-Key"] = CH_PASSWORD

now = (datetime.datetime.now())
print("{} - starting...".format(now))


# create/replace table
now = (datetime.datetime.now())
print("{} - creating/replacing table...".format(now))
response = requests.post(url=CH_URL,
params={"database": "default",
"query": create_replace_stmt,
"session_id": "my-session-id-string"
},
headers=headers)

# select count()
response = requests.post(url=CH_URL,
params={"database": "default",
"query": select_query,
"session_id": "my-session-id-string"
},
headers=headers)

now = (datetime.datetime.now())
print("{} - elements in test_table before insert: {}".format(
now, response.content.decode('utf-8')))


# insert
now = (datetime.datetime.now())
print("{} - Inserting data...".format(now))
response = requests.post(url=CH_URL,
params={"database": "default",
"query": insert_query,
"session_id": "my-session-id-string",
"wait_end_of_query": 1
},
headers=headers)

now = (datetime.datetime.now())
print("{} - Done inserting data...".format(now))

response = requests.post(url=CH_URL,
params={"database": "default",
"query": select_query,
"session_id": "my-session-id-string",
},
headers=headers)

now = (datetime.datetime.now())
print("{} - elements in test_table after insert: {}".format(
now, response.content.decode('utf-8')))

示例预期输出

(venv) ➜  venv/bin/python main.py
2023-07-07 14:54:27.336450 - starting...
2023-07-07 14:54:27.336476 - creating/replacing table...
2023-07-07 14:54:28.125270 - elements in test_table before insert: 0

2023-07-07 14:54:28.125352 - Inserting data...
2023-07-07 14:55:23.788466 - Done inserting data...
2023-07-07 14:55:23.962134 - elements in test_table after insert: 299115357

requirements.txt

requests==2.31.0

有关如何在Python中设置虚拟环境的步骤,请参阅此其他知识库文章