W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
在基于規(guī)則的路徑選擇之后,如果存在多個可以選擇的路徑,那么 OceanBase 數(shù)據(jù)庫會計算每個路徑的代價,并從中選擇代價最小的路徑作為最終選擇的路徑。
OceanBase 數(shù)據(jù)庫的代價模型考慮了 CPU 代價(比如處理一個謂詞的 CPU 開銷)和 IO 代價(比如順序、隨機讀取宏塊和微塊的代價),CPU 代價和 IO 代價最終相加得到一個總的代價。
在 OceanBase 數(shù)據(jù)庫中,每個訪問路徑的代價會在執(zhí)行計劃中都會展示出來。如下例所示:
obclient>CREATE TABLE t1(a INT PRIMARY KEY, b INT, c INT, INDEX k1(b));
Query OK, 0 rows affected (0.35 sec)
/*主表路徑的代價*/
obclient>EXPLAIN SELECT/*+INDEX(t1 PRIMARY)*/ * FROM t1 WHERE b < 10;
+-----------------------------------------------------------------+
| Query Plan |
+-----------------------------------------------------------------+
| ===================================
|ID|OPERATOR |NAME|EST. ROWS|COST|
-----------------------------------
|0 |TABLE SCAN|t1 |200 |622 |
===================================
Outputs & filters:
-------------------------------------
0 - output([t1.a], [t1.b], [t1.c]), filter([t1.b < 10]),
access([t1.b], [t1.a], [t1.c]), partitions(p0)
/* k1 路徑的代價*/
obclient> EXPLAIN SELECT/*+INDEX(t1 k1)*/ * FROM t1 WHERE b < 10;
+--------------------------------------------------------------------+
| Query Plan |
+--------------------------------------------------------------------+
| =====================================
|ID|OPERATOR |NAME |EST. ROWS|COST|
-------------------------------------
|0 |TABLE SCAN|t1(k1)|200 |1114|
=====================================
Outputs & filters:
-------------------------------------
0 - output([t1.a], [t1.b], [t1.c]), filter(nil),
access([t1.b], [t1.a], [t1.c]), partitions(p0)
對于一個訪問路徑,它的代價主要由掃描訪問路徑的代價和回表的代價兩部分組成。如果一個訪問路徑不需要回表,那么就沒有回表的代價。
在 OceanBase 數(shù)據(jù)庫中,訪問路徑的代價取決于很多因素,比如掃描的行數(shù)、回表的行數(shù)、投影的列數(shù)和謂詞的個數(shù)等。但是對于訪問路徑來說,代價在很大程度上取決于行數(shù),所以在下面的示例分析中,從行數(shù)這個維度來介紹這兩部分的代價。
掃描訪問路徑的代價
掃描訪問路徑的代價跟掃描的行數(shù)成正比,理論上來說掃描的行數(shù)越多,執(zhí)行時間就會越久。對于一個訪問路徑,query range 決定了需要掃描的范圍,從而決定了需要掃描的行數(shù)。Query range 的掃描是順序 IO。
回表的代價
回表的代價跟回表的行數(shù)也也是正相關(guān)的,回表的行數(shù)越多(回表的行數(shù)是指滿足所有能在索引上執(zhí)行的謂詞的行數(shù)),執(zhí)行時間就會越長?;乇淼膾呙枋请S機 IO,所以回表一行的代價會比 query range 掃描一行的代價高很多。
當(dāng)分析一個訪問路徑的性能的時候,可以從上面兩個因素入手,獲取通過 query range 掃描的行數(shù)以及回表的行數(shù)。這兩個行數(shù)通??梢酝ㄟ^執(zhí)行 SQL 語句來獲取。
如下例所示,對于查詢 SELECT * FROM t1 WHERE c2 > 20 AND c2 < 800 AND c3 < 200
,索引 k1 的訪問路徑是,首先通常計劃展示來獲取用來抽取 query range 的謂詞,謂詞 c2 > 20 AND c2 < 800
用來抽取 query range,謂詞 c3 < 200
被當(dāng)成回表前的謂詞。那么可以使用如下兩個查詢來檢查 query range 抽取的行數(shù)以及回表之后的行數(shù)。
obclient>CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT, c3 INT, c4 INT, c5 INT, INDEX k1(c2,c3));
Query OK, 0 rows affected (0.26 sec)
obclient>EXPLAIN EXTENDED_NOADDR SELECT/*+INDEX(t1 k1)*/ * FROM t1 WHERE
c2 > 20 AND c2 < 800 AND c3 < 200;
+--------------------------------------------------------------+
| Query Plan |
+--------------------------------------------------------------+
| =====================================
|ID|OPERATOR |NAME |EST. ROWS|COST|
-------------------------------------
|0 |TABLE SCAN|t1(k1)|156 |1216|
=====================================
Outputs & filters:
-------------------------------------
0 - output([t1.c1], [t1.c2], [t1.c3], [t1.c4], [t1.c5]), filter([t1.c3 < 200]),
access([t1.c2], [t1.c3], [t1.c1], [t1.c4], [t1.c5]), partitions(p0),
is_index_back=true, filter_before_indexback[true],
range_key([t1.c2], [t1.c3], [t1.c1]), range(20,MAX,MAX ; 800,MIN,MIN),
range_cond([t1.c2 > 20], [t1.c2 < 800])
/*query range 掃描的行數(shù)*/
obclient>SELECT/*+INDEX(t1 k1)*/ COUNT(*) FROM t1 WHERE c2 > 20 AND c2 < 800;
+----------+
| count(*) |
+----------+
| 779 |
+----------+
1 row in set (0.02 sec)
/* 回表的行數(shù)*/
obclient> SELECT/*+INDEX(t1 k1)*/ COUNT(*) FROM t1 WHERE c2 > 20 AND c2 < 800
AND c3 < 200;
+----------+
| count(*) |
+----------+
| 179 |
+----------+
1 row in set (0.01 sec)
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: