W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
參數(shù)化過(guò)程是指把 SQL 查詢中的常量變成變量的過(guò)程。
同一條 SQL 語(yǔ)句在每次執(zhí)行時(shí)可能會(huì)使用不同的參數(shù),將這些參數(shù)做參數(shù)化處理,可以得到與具體參數(shù)無(wú)關(guān)的 SQL 字符串,并使用該字符串作為計(jì)劃緩存的鍵值,用于在計(jì)劃緩存中獲取執(zhí)行計(jì)劃,從而達(dá)到參數(shù)不同的 SQL 能夠共用相同的計(jì)劃目的。
由于傳統(tǒng)數(shù)據(jù)庫(kù)在進(jìn)行參數(shù)化時(shí)一般是對(duì)語(yǔ)法樹進(jìn)行參數(shù)化,然后使用參數(shù)化后的語(yǔ)法樹作為鍵值在計(jì)劃緩存中獲取計(jì)劃,而 OceanBase 數(shù)據(jù)庫(kù)使用的詞法分析對(duì)文本串直接參數(shù)化后作為計(jì)劃緩存的鍵值,因此叫做快速參數(shù)化。
OceanBase 數(shù)據(jù)庫(kù)支持自適應(yīng)計(jì)劃共享(Adaptive Cursor Sharing)功能以支持不同參數(shù)條件下的計(jì)劃選擇。
基于快速參數(shù)化而獲取執(zhí)行計(jì)劃的流程如下圖所示:
示例解析
obclient>SELECT * FROM T1 WHERE c1 = 5 AND c2 ='oceanbase';
上述示例中的 SQL 查詢參數(shù)化后結(jié)果如下所示,常量 5 和 oceanbase 被參數(shù)化后變成了變量 @1 和 @2:
obclient>SELECT * FROM T1 WHERE c1 = @1 AND c2 = @2;
但在計(jì)劃匹配中,不是所有常量都可以被參數(shù)化,例如 ORDER BY 后面的常量,表示按照 SELECT 投影列中第幾列進(jìn)行排序,所以不可以被參數(shù)化。
如下例所示,表 t1 中含 c1、c2 列,其中 c1 為主鍵列,SQL 查詢的結(jié)果按照 c1 列進(jìn)行排序,由于 c1 作為主鍵列是有序的,所以使用主鍵訪問(wèn)可以免去排序。
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)
但如果執(zhí)行如下命令:
obclient>SELECT c1, c2 FROM t1 ORDER BY 2;
+----+------+
| C1 | C2 |
+----+------+
| 2 | 1 |
| 3 | 1 |
| 1 | 2 |
+----+------+
3 rows in set (0.00 sec)
則結(jié)果需要對(duì) c2 排序,因此需要執(zhí)行顯示的排序操作,執(zhí)行計(jì)劃如下例所示:
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 后面的常量參數(shù)化,不同 ORDER BY 的值具有相同的參數(shù)化后的 SQL,從而導(dǎo)致命中錯(cuò)誤的計(jì)劃。除此之外,如下場(chǎng)景中的常量均不能參數(shù)化(即參數(shù)化的約束條件):
ORDER BY 1,2;
?)GROUP BY 1,2;
?)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”,指定輸入時(shí)間戳的同時(shí),隱含指定了函數(shù)處理的精度值為毫秒)為了解決上面這種可能存在的誤匹配問(wèn)題,在硬解析生成執(zhí)行計(jì)劃過(guò)程中會(huì)對(duì) SQL 請(qǐng)求使用分析語(yǔ)法樹的方法進(jìn)行參數(shù)化,并獲取相應(yīng)的不一致的信息。例如,某語(yǔ)句對(duì)應(yīng)的信息是“快速參數(shù)化參數(shù)數(shù)組的第 3 項(xiàng)必須為數(shù)字 3”,可將其稱為“約束條件”。
對(duì)于下例所示的 Q1 查詢:
Q1:
obclient>SELECT c1, c2, c3 FROM t1
WHERE c1 = 1 AND c2 LIKE 'senior%' ORDER BY 3;
經(jīng)過(guò)詞法分析,可以得到參數(shù)化后的 SQL 語(yǔ)句如下例所示:
obclient>SELECT c1, c2, c3 FROM t1
WHERE c1 = @1 AND c2 LIKE @2 ORDER BY @3 ;
/*參數(shù)化數(shù)組為 {1,‘senior%’ ,3}*/
當(dāng) ORDER BY 后面的常量不同時(shí),不能共用相同的執(zhí)行計(jì)劃,因此在通過(guò)分析語(yǔ)法樹進(jìn)行參數(shù)化時(shí)會(huì)獲得另一種參數(shù)化結(jié)果,如下例所示:
obclient>SELECT c1, c2, c3 FROM t1
WHERE c1 = @1 AND c2 LIKE @2 ORDER BY 3 ;
/*參數(shù)化數(shù)組為{1, ‘senior’}
約束條件為“快速參數(shù)化參數(shù)數(shù)組的第 3 項(xiàng)必須為數(shù)字 3”*/
Q1 請(qǐng)求新生成的參數(shù)化后的文本及約束條件和執(zhí)行計(jì)劃均會(huì)存入計(jì)劃緩存中。
當(dāng)用戶再次發(fā)出如下 Q2 請(qǐng)求命令:
Q2:
obclient>SELECT c1, c2, c3 FROM t1
WHERE c1 = 1 AND c2 LIKE 'senior%' ORDER BY 2;
經(jīng)過(guò)快速參數(shù)化后結(jié)果如下例所示:
obclient>SELECT c1, c2, c3 FROM t1
WHERE c1 = @1 and c2 like @2 ORDER BY @3;
/*參數(shù)化數(shù)組為 {1,'senior%' ,2}*/
這與 Q1 請(qǐng)求快速參數(shù)化后 SQL 結(jié)果一樣,但由于不滿足“快速參數(shù)化參數(shù)數(shù)組的第 3 項(xiàng)必須為數(shù)字 3”這個(gè)約束條件,無(wú)法匹配該計(jì)劃。此時(shí) Q2 會(huì)通過(guò)硬解析生成新的執(zhí)行計(jì)劃及約束條件(即“快速參數(shù)化參數(shù)數(shù)組的第 3 項(xiàng)必須為數(shù)字 2”),并將新的計(jì)劃和約束條件加入到緩存中,這樣在下次執(zhí)行 Q1 和 Q2 時(shí)均可命中對(duì)應(yīng)正確的執(zhí)行計(jì)劃。
基于快速參數(shù)化的執(zhí)行計(jì)劃緩存優(yōu)點(diǎn)如下:
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: