<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                [TOC] # 快速參數化 參數化過程是指把 SQL 查詢中的常量變成變量的過程。 同一條 SQL 語句在每次執行時可能會使用不同的參數,將這些參數做參數化處理,可以得到與具體參數無關的 SQL 字符串,并使用該字符串作為計劃緩存的鍵值,用于在計劃緩存中獲取執行計劃,從而達到參數不同的 SQL 能夠共用相同的計劃目的。 由于傳統數據庫在進行參數化時一般是對語法樹進行參數化,然后使用參數化后的語法樹作為鍵值在計劃緩存中獲取計劃,而 OceanBase 數據庫使用的詞法分析對文本串直接參數化后作為計劃緩存的鍵值,因此叫做快速參數化。 OceanBase 數據庫支持自適應計劃共享(Adaptive Cursor Sharing)功能以支持不同參數條件下的計劃選擇。 基于快速參數化而獲取執行計劃的流程如下圖所示: ![](https://img.kancloud.cn/21/0a/210ac762541d5daf59253579ce5119d0_831x387.png) **示例解析** ~~~ obclient>SELECT * FROM T1 WHERE c1 = 5 AND c2 ='oceanbase'; ~~~ 上述示例中的 SQL 查詢參數化后結果如下所示,常量 5 和 oceanbase 被參數化后變成了變量 @1 和 @2: ~~~ obclient>SELECT * FROM T1 WHERE c1 = @1 AND c2 = @2; ~~~ 但在計劃匹配中,不是所有常量都可以被參數化,例如 ORDER BY 后面的常量,表示按照 SELECT 投影列中第幾列進行排序,所以不可以被參數化。 如下例所示,表 t1 中含 c1、c2 列,其中 c1 為主鍵列,SQL 查詢的結果按照 c1 列進行排序,由于 c1 作為主鍵列是有序的,所以使用主鍵訪問可以免去排序。 ~~~ obclient>CREATE TABLE t1(c1 INT PRIMARY KEY,c2 INT); Query OK, 0 rows affected (0.06 sec) obclient>INSERT INTO t1 VALUES (1,2); Query OK, 1 row affected (0.01 sec) obclient>INSERT INTO t1 VALUES (2,1); Query OK, 1 row affected (0.01 sec) obclient>INSERT INTO t1 VALUES (3,1); Query OK, 1 row affected (0.01 sec) obclient>SELECT c1, c2 FROM t1 ORDER BY 1; +----+------+ | C1 | C2 | +----+------+ | 1 | 2 | | 2 | 1 | | 3 | 1 | +----+------+ 3 rows in set (0.00 sec) obclient>EXPLAIN SELECT c1, c2 FROM t1 ORDER BY 1\G; *************************** 1. row *************************** Query Plan: | =================================== |ID|OPERATOR |NAME|EST. ROWS|COST| ----------------------------------- |0 |TABLE SCAN|t1 |1000 |1381| =================================== Outputs & filters: ------------------------------------- 0 - output([T1.C1], [T1.C2]), filter(nil), access([T1.C1], [T1.C2]), partitions(p0) ~~~ 但如果執行如下命令: ~~~ obclient>SELECT c1, c2 FROM t1 ORDER BY 2; +----+------+ | C1 | C2 | +----+------+ | 2 | 1 | | 3 | 1 | | 1 | 2 | +----+------+ 3 rows in set (0.00 sec) ~~~ 則結果需要對 c2 排序,因此需要執行顯示的排序操作,執行計劃如下例所示: ~~~ obclient>EXPLAIN SELECT c1, c2 FROM t1 ORDER BY 2\G; *************************** 1. row *************************** Query Plan: | ==================================== |ID|OPERATOR |NAME|EST. ROWS|COST| ------------------------------------ |0 |SORT | |1000 |1886| |1 | TABLE SCAN|t1 |1000 |1381| ==================================== Outputs & filters: ------------------------------------- 0 - output([T1.C1], [T1.C2]), filter(nil), sort_keys([T1.C2, ASC]) 1 - output([T1.C1], [T1.C2]), filter(nil), access([T1.C1], [T1.C2]), partitions(p0) ~~~ 因此,如果將 ORDER BY 后面的常量參數化,不同 ORDER BY 的值具有相同的參數化后的 SQL,從而導致命中錯誤的計劃。除此之外,如下場景中的常量均不能參數化(即參數化的約束條件): * 所有 ORDER BY 后常量(例如`ORDER BY 1,2;`) * 所有 GROUP BY 后常量(例如`GROUP BY 1,2;`) * LIMIT 后常量(例如`LIMIT 5;`) * 作為格式串的字符串常量(例如`SELECT DATE_FORMAT('2006-06-00', '%d');`里面的`%d`) * 函數輸入參數中,影響函數結果并最終影響執行計劃的常量(例如`CAST(999.88 as NUMBER(2,1))`中的`NUMBER(2,1)`,或者`SUBSTR('abcd', 1, 2)`中的 1 和 2) * 函數輸入參數中,帶有隱含信息并最終影響執行計劃的常量(例如`SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19.012');`里面的“2015-11-13 10:20:19.012”,指定輸入時間戳的同時,隱含指定了函數處理的精度值為毫秒) 為了解決上面這種可能存在的誤匹配問題,在硬解析生成執行計劃過程中會對 SQL 請求使用分析語法樹的方法進行參數化,并獲取相應的不一致的信息。例如,某語句對應的信息是“快速參數化參數數組的第 3 項必須為數字 3”,可將其稱為“約束條件”。 對于下例所示的 Q1 查詢: ~~~ Q1: obclient>SELECT c1, c2, c3 FROM t1 WHERE c1 = 1 AND c2 LIKE 'senior%' ORDER BY 3; ~~~ 經過詞法分析,可以得到參數化后的 SQL 語句如下例所示: ~~~ obclient>SELECT c1, c2, c3 FROM t1 WHERE c1 = @1 AND c2 LIKE @2 ORDER BY @3 ; /*參數化數組為 {1,‘senior%’ ,3}*/ ~~~ 當 ORDER BY 后面的常量不同時,不能共用相同的執行計劃,因此在通過分析語法樹進行參數化時會獲得另一種參數化結果,如下例所示: ~~~ obclient>SELECT c1, c2, c3 FROM t1 WHERE c1 = @1 AND c2 LIKE @2 ORDER BY 3 ; /*參數化數組為{1, ‘senior’} 約束條件為“快速參數化參數數組的第 3 項必須為數字 3”*/ ~~~ Q1 請求新生成的參數化后的文本及約束條件和執行計劃均會存入計劃緩存中。 當用戶再次發出如下 Q2 請求命令: ~~~ Q2: obclient>SELECT c1, c2, c3 FROM t1 WHERE c1 = 1 AND c2 LIKE 'senior%' ORDER BY 2; ~~~ 經過快速參數化后結果如下例所示: ~~~ obclient>SELECT c1, c2, c3 FROM t1 WHERE c1 = @1 and c2 like @2 ORDER BY @3; /*參數化數組為 {1,'senior%' ,2}*/ ~~~ 這與 Q1 請求快速參數化后 SQL 結果一樣,但由于不滿足“快速參數化參數數組的第 3 項必須為數字 3”這個約束條件,無法匹配該計劃。此時 Q2 會通過硬解析生成新的執行計劃及約束條件(即“快速參數化參數數組的第 3 項必須為數字 2”),并將新的計劃和約束條件加入到緩存中,這樣在下次執行 Q1 和 Q2 時均可命中對應正確的執行計劃。 基于快速參數化的執行計劃緩存優點如下: * 節省了語法分析過程。 * 查找 HASH MAP 時,可以將對參數化后語法樹的 HASH 和比較操作,替換為對文本串進行 HASH 和 MEMCMP 操作,以提高執行效率。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看