
# Doris数据查询规范
该章节主要介绍Doris数据查询时需遵循的规则和建议。
#### Doris数据查询规则
- 在数据查询业务代码中建议查询失败时进行重试，再次下发查询。
- **IN**中常量枚举值超过1000后，必须修改为子查询。
- 禁止使用REST API（Statement Execution Action）执行大量SQL查询，该接口仅用于集群维护。
- 查询条件返回结果超过5万条，则使用JDBC Catalog或者OUTFILE方式导出查询数据，否则FE上大量数据传输将占用FE资源，影响集群稳定性。
  - 如果是交互式查询，建议使用分页方式（offset limit）导出数据，分页命令为**order by**。
  
  - 如果数据导出提供给第三方使用，建议使用OUTFILE或者Export方式导出数据。
   
- 2个以上大于3亿的表JOIN使用Colocate Join。
- 亿级别大表禁止使用**SELECT \*** 查询数据，查询时需明确要查询的字段。
  - 使用SQL Block方式禁止**SELECT \***操作。
  
  - 如果是高并发点查询，建议开启行存储（Doris 2.x版本支持），并且使用PreparedStatement查询。
   
- 亿级以上表数据查询必须设置分区分桶条件。
- 禁止对分区表执行全分区数据扫描操作。
- 针对部分Doris查询执行时间较长且耗费较多内存和CPU资源的情况，可以通过在SQL或user级别设置查询超时时间参数"query_timeout"来优化系统性能和资源管理。
 
#### Doris数据查询建议
- 一次**INSERT INTO SELECT** 数据超过1亿条后，建议拆分为多个**INSERT INTO SELECT**语句执行，分成多个批次来执行。
- 不要使用OR作为JOIN条件。
- 不建议频繁地进行数据delete修改操作，将要删除的数据攒批，偶尔进行批量删除，且需要带上条件，提升系统稳定性和删除效率。
- 大量数据排序（5亿以上）后返回部分数据，建议先减少数据范围再执行排序，否则大量排序会影响性能。 例如：
  将**from table order by datetime desc limit** *10* 优化为**from table where datetime='** *2023-10-20* **' order by datetime desc limit** *10*。
  
- 查询任务性能调优参数**parallel_fragment_exec_instance_num** 使用注意事项：
  此参数是session级别设置，表示可并发执行的fragment数量，对CPU消耗较大，因此一般情况下不需要设置此参数。如果需要设置此参数来加速查询性能，必须遵循以下规则：
  - 切勿设置该参数为全局生效，禁止使用**set global**方式进行设置。
  
  - 设置参数值建议为偶数2或4（最大值不要超过单节点CPU核数的一半）。
  
  - 设置此参数值时需要观察CPU使用率，CPU使用率小于50%时方可考虑设置。
  
  - 如果查询SQL是**INSERT INTO SELECT**大数据量的方式，不建议设置此参数。
   
- 执行特殊的大SQL操作时，可以使用类似**SELECT /\*+ SET_VAR(query_timeout = xxx) \*/ \* FROM table**通过Hint方式设置Session会话变量，不要设置全局的系统变量。
 
