
# Query执行流程
SQL引擎从接受SQL语句到执行SQL语句需要经历的步骤如[图1]和[表1]所示。其中，红色字体部分为DBA可以介入实施调优的环节。
图1SQL引擎执行查询类SQL语句的流程   
![](https://support.huaweicloud.com/centralized-devg-v2-gaussdb/figure/zh-cn_image_0000002220980685.png "点击放大")
 表1SQL引擎执行查询类SQL语句的步骤说明 
| 步骤         | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
|:---|:---|
| 1、语法\&词法解析 | 按照约定的SQL语句规则，把输入的SQL语句从字符串转化为格式化结构(Stmt)。                                                                                                                                                                                                                                                                                                                                                                                                                       |
| 2、语义解析     | 将"语法\&词法解析"输出的格式化结构转化为数据库可以识别的对象。                                                                                                                                                                                                                                                                                                                                                                                                                               |
| 3、查询重写     | 根据规则把"语义解析"的输出等价转化为执行上更为优化的结构。                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| 4、查询优化     | 根据"查询重写"的输出和数据库内部的统计信息规划SQL语句具体的执行方式，也就是执行计划。统计信息和GUC参数对查询优化（执行计划）的影响，请参见[调优手段之统计信息]和[调优手段之GUC参数]。 |
| 5、查询执行     | 根据"查询优化"规划的执行路径执行SQL查询语句。底层存储方式的选择合理性，将影响查询执行效率。                                                                                                                                                                                                                                                                                                                                                                                                                |
   
 #### 调优手段之统计信息
GaussDB优化器是典型的基于代价的优化 (Cost-Based Optimization，简称CBO)。在这种优化器模型下，数据库根据表的元组数、字段宽度、NULL记录比率、distinct值、MCV值、HB值等表的特征值，以及一定的代价计算模型，计算出每一个执行步骤的不同执行方式的输出元组数和执行代价(cost)，进而选出整体执行代价最小/首元组返回代价最小的执行方式进行执行。这些特征值就是统计信息。从上面描述可以看出统计信息是查询优化的核心输入，准确的统计信息将帮助规划器选择最合适的查询规划，一般来说我们通过analyze语法收集整个表或者表的若干个字段的统计信息，周期性地运行ANALYZE，或者在对表的大部分内容做了更改之后马上运行它是个好习惯。
注意，DDL可能会导致统计信息发生变化，进而导致计划跳变。当表上做了DDL操作后，应注意统计信息是否需要重新收集。
 #### 调优手段之GUC参数
查询优化的主要目的是为查询语句选择高效的执行方式。
如下SQL语句:
```
select count(1) 
from customer inner join store_sales on (ss_customer_sk = c_customer_sk);
```
在执行customer inner join store_sales的时候，GaussDB支持Nested Loop、Merge Join和Hash Join三种不同的Join方式。优化器会根据表customer和表store_sales的统计信息估算结果集的大小以及每种Join方式的执行代价，然后对比选出执行代价最小的执行计划。
正如前面所说，执行代价计算都是基于一定的模型和统计信息进行估算，当因为某些原因代价估算不能反映真实的cost的时候，就需要通过GUC参数设置的方式让执行计划倾向更优规划。例如：random_page_cost参数表示优化器计算一次非顺序抓取磁盘页面的开销，该参数默认值为4。当机器磁盘随机读取的速度较快时，比如SSD设备，可以将该参数的值适当调小，更改后，索引扫描的代价降低，生成计划时更倾向于选择索引扫描的方式。
#### 调优手段之SQL重写
除了上述干预SQL引擎所生成执行计划的执行性能外，根据数据库的SQL执行机制以及大量的实践发现，有些场景下，在保证客户业务SQL逻辑的前提下，通过一定规则由DBA重写SQL语句，可以大幅度地提升SQL语句的性能。
这种调优场景对DBA的要求比较高，需要对客户业务有足够的了解，同时也需要扎实的SQL语句基本功，后续会介绍几个常见的SQL改写场景。
