作为一款 OLAP 分析型数据库,数据查询是 ClickHouse 的主要工作之一,虽然 ClickHouse 拥有优秀的查询性能,使用不恰当的 SQL 语句进行查询不仅会带来低性能,还可能导致不可预知的系统错误。比如:
ClickHouse 对于 SQL 语句的解析是大小写敏感的,这意味着SELECT a 和SELECT A 表示的语义是不相同的。
在绝大部分场景中,都应该避免使用 SELECT * 形式来查询数据,因为通配符对于采用列式存储的 ClickHouse 而言没有任何好处。
-- 假如面对一张拥有数百个列字段的数据表,下面这两条 SELECT 语句的性能可能会相差100倍之多:
SELECT * FROM datasets.hits_v1;
SELECT WatchID FROM datasets.hits_v1;
只有少数情况下使用 SELECT * 是合理的:
LIMIT 1 。但是更好的方式是使用 DESC TABLE 查询。PREWHERE 进行强过滤时。ClickHouse目前支持的查询子句如下所示:
[WITH expr |(subquery)]
SELECT [DISTINCT] expr
[FROM [db.]table | (subquery) | table_function] [FINAL]
[SAMPLE expr]
[[LEFT] ARRAY JOIN]
[GLOBAL] [ALL|ANY|ASOF] [INNER | CROSS | [LEFT|RIGHT|FULL [OUTER]] ] JOIN (subquery)|table ON|USING columns_list
[PREWHERE expr]
[WHERE expr]
[GROUP BY expr] [WITH ROLLUP|CUBE|TOTALS]
[HAVING expr]
[ORDER BY expr]
[LIMIT [n[,m]]
[UNION ALL]
[INTO OUTFILE filename]
[FORMAT format]
[LIMIT [offset] n BY columns]
ClickHouse 对于查询语法的解析也大致是按照上面各个子句排列的顺序进行的。
虽然 SELECT 位于 SQL 语句的起始位置,但它却是在上述一众子句之后执行的。在其他子句执行之后,SELECT 会将选取的字段或表达式作用于每行数据之上。
在选择列字段时,ClickHouse 还为特定场景提供了一种基于正则查询的形式。
-- 执行下面的语句后,查询会返回名称以字母 n 开头和包含字母 p 的列字段
SELECT COLUMNS('^n'), COLUMNS('p') FROM system.databases
┌─name───────┬─data_path───────┬─metadata_path──────┐
│ default │ /data/default/ │ /metadata/default/ │
│ system │ /data/system/ │ /metadata/system/ │
└────────────┴─────────────────┴────────────────────┘