
# ClickHouse数据查询规范
该章节主要介绍ClickHouse数据查询时需遵循的规范和建议。
#### 数据查询
- 【规则】不要使用select \*，只查询需要的字段，减少机器负载，提升查询性能。 OLAP分析场景，一张大宽表通常能有几百甚至上千列，选择其中少数的几列做维度列、指标列计算。在这种场景下，ClickHouse的数据也是按照列存储。如果使用select \*，会加重系统的压力。
  
- 【规则】通过limit限制查询返回的数据量，节省计算资源、减少网络开销。 如果返回的数据量过大，客户端有可能出现内存溢出等服务异常。在前端使用ClickHouse的场景下，如果要查询的数据量比较大，建议每次可适当的进行分页查询返回数据，以减少查询数据量对网络带宽和计算资源的占用。
  
- 【规则】关联查询必须大表join小表。 对于ClickHouse来说，原则上需要把多表join模型提前加工为宽表模型，多个表以及维度表变化比较频繁情况下，不适合进行宽表加工处理，必须使用Join模型以实时查询到最新数据。两个表做join操作，建议大表join小表，必须使用关联条件。小表的数据量控制在百万\~千万行级别，且需要在join前把小表数据通过条件进行有效过滤。
  
- 【建议】使用GLOBAL JOIN/IN替换普通的JOIN。 ClickHouse基于分布式表查询会转换成所有分片的本地表操作，再汇总结果。实际使用中，join和global join的执行逻辑差别很大，建议使用global join做分布式表查询。
  
- 【规则】合理使用数据表的分区字段和索引字段。
  - MergeTree引擎，数据是以分区目录形式进行组织存储的，在进行数据查询时，使用分区可以有效跳过无用的数据文件，减少数据的读取。
  
  - MergeTree引擎会根据索引字段进行数据排序，并且根据index_granularity的配置生成稀疏索引。根据索引字段查询，能快速过滤数据，减少数据的读取，大幅度提升查询性能。
   
- 【建议】明确数据查询的范围。 增加条件过滤和查询数据周期过滤，缩小数据查询范围。例如查询指定分区，通过指定分区字段会减少底层数据库扫描的文件数量，提升查询性能。例如：700个分区的千列大表，需要查询一个分区中有7000万数据，其他699个分区中无数据，虽然只有一个分区有数据，其他分区无数据，但是查询指定分区为百毫秒级性能，没有指定分区查询性能为1\~2秒左右，性能相差20倍。
  
- 【建议】慎用final查询。 在查询语句的最后跟上final，通常是对于ReplacingMergeTree引擎，数据不能完全去重情况下，少数开发人员习惯使用final关键字进行实时合并去重操作（merge-on-read），保证查询数据无重复数据。可以通过argMax函数或其他方式规避此问题。
  
- 【建议】使用物化视图加速查询。 对于固定查询方式的场景，建议使用物化视图，提前做好数据聚合，相对于查询明细表，性能有数量级的提升。
  
- 【建议】物化视图创建时不会进行语法校验，只有发生实际数据插入与查询时才会出错。物化视图上线前，需做好充分验证。
 
