[TOC] # DISTINCT DISTINCT 算子用于为对数据行去重,包括去除重复的 NULL 值。 DISTINCT 算子包括 HASH DISTINCT 和 MERGE DISTINCT。 ## HASH DISTINCT HASH DISTINCT 算子使用 HASH 算法执行 DISTINCT 运算。 示例 1:使用 HASH 算法执行 DISTINCT 运算,对 t1 表的 c1 列进行去重处理 ~~~ obclient>CREATE TABLE t1(c1 INT, c2 INT); Query OK, 0 rows affected (0.09 sec) obclient>CREATE TABLE t2(c1 INT, c2 INT); Query OK, 0 rows affected (0.09 sec) obclient>EXPLAIN SELECT /*+USE_HASH_AGGREGATION*/ DISTINCT c1 FROM t1\G; *************************** 1. row *************************** Query Plan: |======================================= |ID|OPERATOR |NAME|EST. ROWS|COST | --------------------------------------- |0 |HASH DISTINCT| |101 |99169| |1 | TABLE SCAN |t1 |100000 |66272| ======================================= Outputs & filters: ------------------------------------- 0 - output([t1.c1]), filter(nil), distinct([t1.c1]) 1 - output([t1.c1]), filter(nil), access([t1.c1]), partitions(p0) ~~~ 上述示例中,执行计划展示中 0 号算子 HASH DISTINCT 执行去重运算,outputs & filters 详细展示了 HASH DISTINCT 算子的具体输出信息如下: <table data-tag="table" id="table-z3j-lmv-ctp" class="table"><colgroup width="240" span="1" data-tag="col" id="col-jfd-vgr-xnr" colwidth="1*" colnum="1" colname="col1" style="width:50%" class="col"></colgroup><colgroup width="505" span="1" data-tag="col" id="col-qm8-kcd-gcc" colwidth="1*" colnum="2" colname="col2" style="width:50%" class="col"></colgroup><thead id="thead-nqa-thf-ou3" class="thead"><tr id="tr-k5x-6k4-euo"><th id="td-2ac-t11-aeu"><p id="p-a5e-qy9-odf"><b>信息名称</b></p></th><th id="td-8g1-p8b-2u8"><p id="p-jhd-hvz-cpc"><b>含义</b></p></th></tr></thead><tbody data-tag="tbody" id="tbody-l6k-yg7-ikj" class="tbody"><tr data-tag="tr" id="tr-92z-54k-jnv" class="tr"><td data-tag="td" id="td-7jn-qka-1xv" class="td"><p data-tag="p" id="p-lg6-17g-l1r" class="p">output </p></td><td data-tag="td" id="td-yzu-vr1-byp" class="td"><p id="p-nqo-ngu-9mi">该算子的输出列。</p></td></tr><tr data-tag="tr" id="tr-fj2-m63-q0n" class="tr"><td id="td-79h-mfo-osl"><p id="p-1jz-luk-5wr">filter</p></td><td id="td-4fs-4pj-vlf"><p id="p-u8s-z70-e2b">该算子的过滤谓词。</p><p id="p-ggi-rlw-ag6">由于示例中 HASH DISTINCT 算子没有设置 filter,所以为 nil。</p></td></tr><tr data-tag="tr" id="tr-kfz-m0d-rpj" class="tr"><td data-tag="td" id="td-9wt-9rh-gne" class="td"><p data-tag="p" id="p-laz-dmf-0p5" class="p">partition</p></td><td data-tag="td" id="td-99z-8t3-mb0" class="td"><p id="p-cw7-ibv-zmt">查询需要扫描的分区。</p></td></tr><tr data-tag="tr" id="tr-yts-1xz-cxz" class="tr"><td id="td-jj7-czs-ikh"><p id="p-2l2-ad2-7vt">distinct</p></td><td id="td-i61-74k-d10"><p id="p-4zm-yba-l35">指定需要去重的列。</p><p id="p-jgk-clp-js4">例如,<code data-tag="code" class="code">distinct([t1.c1])</code> 的参数 <code data-tag="code" class="code">t1.c1</code> 指定对 t1 表的 c1 列进行去重处理,并且采用 HASH 算法。</p></td></tr></tbody></table> ## MERGE DISTINCT MERGE DISTINCT 算子使用 MERGE 算法执行 DISTINCT 运算。 示例 2:使用 MERGE 算法执行 DISTINCT 运算 ~~~ obclient>EXPLAIN SELECT /*+NO_USE_HASH_AGGREGATION*/ DISTINCT c1 FROM t1\G; *************************** 1. row *************************** Query Plan: |======================================= |ID|OPERATOR |NAME|EST. ROWS|COST| --------------------------------------- |0 |MERGE DISTINCT| |3 |40 | |1 | SORT | |3 |39 | |2 | TABLE SCAN |t1 |3 |37 | ======================================= Outputs & filters: ------------------------------------- 0 - output([t1.c1]), filter(nil), distinct([t1.c1]) 1 - output([t1.c1]), filter(nil), sort_keys([t1.c1, ASC]) 2 - output([t1.c1]), filter(nil), access([t1.c1]), partitions(p0) ~~~ 上述示例中,0 号算子 MERGE DISTINCT 执行去重运算,采用了 MERGE 算法,并且由于 2 号算子输出的数据是无序的,而 MERGE DISTINCT 算子需要输入的数据有序,所以在执行去重运算前需要使用 SORT 算子对数据排序。执行计划展示中的 outputs & filters 详细展示了 MERGE DISTINCT 算子的输出信息如下: <table data-tag="table" id="table-4jq-ykx-zy7" class="table"><colgroup width="240" span="1" data-tag="col" id="col-7w2-yea-ea9" colwidth="1*" colnum="1" colname="col1" style="width:50%" class="col"></colgroup><colgroup width="505" span="1" data-tag="col" id="col-7ah-u04-1h3" colwidth="1*" colnum="2" colname="col2" style="width:50%" class="col"></colgroup><thead id="thead-6mq-pnm-ee7" class="thead"><tr id="tr-nb6-cjs-ehg"><th id="td-942-2me-ow6"><p id="p-uwe-uyl-6em"><b>信息名称</b></p></th><th id="td-88k-ehf-xqj"><p id="p-jta-4a8-1ks"><b>含义</b></p></th></tr></thead><tbody data-tag="tbody" id="tbody-eqy-bnq-yv2" class="tbody"><tr data-tag="tr" id="tr-h0d-1g4-dzy" class="tr"><td data-tag="td" id="td-z34-x40-2ax" class="td"><p data-tag="p" id="p-eey-ovq-i4e" class="p">output </p></td><td data-tag="td" id="td-dvg-wii-jvs" class="td"><p id="p-ws1-d5e-9ep">该算子的输出列。</p></td></tr><tr data-tag="tr" id="tr-dsf-bf5-8o3" class="tr"><td id="td-tno-tcv-hms"><p id="p-56d-ipa-l0j">filter</p></td><td id="td-z4q-1v4-vp1"><p id="p-rn1-sh7-hqb">该算子的过滤谓词。</p><p id="p-t7n-1kv-wac">由于示例中 MERGE DISTINCT 算子没有设置 filter,所以为 nil。</p></td></tr><tr data-tag="tr" id="tr-3oc-hle-6ff" class="tr"><td id="td-iog-zdi-iaq"><p id="p-16n-yjv-cwu">distinct</p></td><td id="td-ccn-eye-3ak"><p id="p-blb-me5-s6d">指定需要去重的列。</p><p id="p-mti-b2v-k84">例如,<code data-tag="code" class="code">distinct([t1.c1])</code> 的参数 <code data-tag="code" class="code">t1.c1</code> 指定对 t1 表的 c1 列进行去重处理,并且采用 MERGE 算法。</p></td></tr></tbody></table>