[TOC] # SQL 请求执行流程 SQL 引擎从接受 SQL 请求到执行的典型流程如下图所示: ![](https://img.kancloud.cn/ef/5d/ef5d701f0a19e154bfc718233a44dab7_387x607.png) <table data-tag="table" id="table-vp6-ho3-4bq" class="table"><colgroup width="228" span="1" data-tag="col" id="col-bxu-3jv-kco" colwidth="1*" colnum="1" colname="col1" style="width:50%" class="col"></colgroup><colgroup width="524" span="1" data-tag="col" id="col-427-fzn-6qf" colwidth="1*" colnum="2" colname="col2" style="width:50%" class="col"></colgroup><thead id="thead-akx-qkt-366" class="thead"><tr id="tr-88w-mww-u6l"><th id="td-vav-0fi-jho"><p id="p-hy5-mnu-rnd"><b>步骤</b></p></th><th id="td-4o9-y40-3fu"><p id="p-brf-36e-6oc"><b>说明</b></p></th></tr></thead><tbody data-tag="tbody" id="tbody-nf6-t5v-h0n" class="tbody"><tr data-tag="tr" id="tr-5t7-x10-rxi" class="tr"><td data-tag="td" id="td-mbt-mvv-23o" class="td"><p data-tag="p" id="p-m0a-35t-236" class="p">Parser(词法/语法解析模块)</p></td><td data-tag="td" id="td-2vz-qwf-5k1" class="td"><p data-tag="p" id="p-kyg-imt-zfg" class="p">在收到用户发送的 SQL 请求串后,Parser 会将字符串分成一个个的“单词”,并根据预先设定好的语法规则解析整个请求,将 SQL 请求字符串转换成带有语法结构信息的内存数据结构,称为“语法树”(Syntax Tree)。</p></td></tr><tr data-tag="tr" id="tr-g76-aq1-a11" class="tr"><td data-tag="td" id="td-pdx-938-bxv" class="td"><p data-tag="p" id="p-zzc-9gs-42m" class="p">Plan Cache(执行计划缓存模块)</p></td><td data-tag="td" id="td-w4s-ujy-1hy" class="td"><p data-tag="p" id="p-nqy-mdo-pd6" class="p">执行计划缓存模块会将该 SQL 第一次生成的执行计划缓存在内存中,后续的执行可以反复执行这个计划,避免了重复查询优化的过程。</p></td></tr><tr data-tag="tr" id="tr-fam-i2u-mvc" class="tr"><td data-tag="td" id="td-fm1-xh3-n12" class="td"><p data-tag="p" id="p-uoj-dkt-l1o" class="p">Resolver(语义解析模块)</p></td><td data-tag="td" id="td-9xp-k7k-kbk" class="td"><p data-tag="p" id="p-erk-bur-pke" class="p">Resolver 将生成的“语法树”转换为带有数据库语义信息的内部数据结构。在这一过程中,Resolver 将根据数据库元信息将 SQL 请求中的 token 翻译成对应的对象(例如库、表、列、索引等),生成的数据结构叫做 Statement Tree。</p></td></tr><tr data-tag="tr" id="tr-oig-0bm-8d2" class="tr"><td data-tag="td" id="td-uek-75j-n2p" class="td"><p data-tag="p" id="p-l9z-uc9-ckl" class="p">Transfomer(逻辑改写模块)</p></td><td data-tag="td" id="td-cmn-l6s-e92" class="td"><p data-tag="p" id="p-ztk-g6r-ff4" class="p">分析用户 SQL 的语义,并根据内部的规则或代价模型,将用户 SQL“改写”为与之等价的其他形式,并将其提供给后续的优化器做进一步的优化。Transformer 的工作方式是在原 Statement Tree 上做等价变换,变换的结果仍然是一棵 Statement Tree。</p></td></tr><tr data-tag="tr" id="tr-hc2-ick-3rk" class="tr"><td data-tag="td" id="td-tkh-py8-w51" class="td"><p data-tag="p" id="p-hfc-68m-tov" class="p">Optimizer(优化器)</p></td><td data-tag="td" id="td-yxs-h9b-m7a" class="td"><p data-tag="p" id="p-8nv-stg-r0v" class="p">优化器是整个 SQL 请求优化的核心,其作用是为 SQL 请求生成最佳的执行计划。在优化过程中,优化器需要综合考虑 SQL 请求的语义、对象数据特征、对象物理分布等多方面因素,解决访问路径选择、联接顺序选择、联接算法选择、分布式计划生成等多个核心问题,最终选择一个对应该 SQL 的最佳执行计划。</p></td></tr><tr data-tag="tr" id="tr-ufr-wd2-0al" class="tr"><td data-tag="td" id="td-az5-jem-adx" class="td"><p data-tag="p" id="p-qfx-kk8-7xk" class="p">Code Generator(代码生成器)</p></td><td data-tag="td" id="td-qib-1tn-0m6" class="td"><p data-tag="p" id="p-5od-01m-9il" class="p">将执行计划转换为可执行的代码,但是不做任何优化选择。</p></td></tr><tr data-tag="tr" id="tr-5mb-poj-jft" class="tr"><td data-tag="td" id="td-z9b-m9s-vcc" class="td"><p data-tag="p" id="p-tkw-s9w-ptv" class="p">Executor(执行器)</p></td><td data-tag="td" id="td-gob-ofx-cvf" class="td"><p data-tag="p" id="p-ecc-4fi-xix" class="p">启动 SQL 的执行过程。</p><ul lake-indent="0" data-tag="ul" id="ul-r06-vza-kb5" class="ul"><li data-tag="li" id="li-bdk-d7m-vq5" class="li"><p id="p-nec-xpu-3hl">对于本地执行计划,Executor 会简单的从执行计划的顶端的算子开始调用,根据算子自身的逻辑完成整个执行的过程,并返回执行结果。</p></li><li data-tag="li" id="li-cem-tri-e7d" class="li"><p id="p-atc-v2q-xah">对于远程或分布式计划,将执行树分成多个可以调度的子计划,并通过 RPC 将其发送给相关的节点去执行。 </p></li></ul></td></tr></tbody></table>