天天看點

OceanBase 全局索引與局部索引探索

作者:愛可生開源社群

OceanBase 全局索引與局部索引探索導緻的本區域查找和跨區域查找。

作者:網名大資料模型,對制造業、銀行業、通訊業了解多一點,關心專注國産資料庫技術布道以及資料資産建設的應用實踐。

愛可生開源社群出品,原創内容未經授權不得随意使用,轉載請聯系小編并注明來源。

本文約 1200 字,預計閱讀需要 4 分鐘。

OceanBase 的索引

索引和分區是資料庫的關鍵核心基本功能,OceanBase 是一個單體分布式的架構,具有高性能、高擴充、高可用的特點,索引和分區立了大功。

OceanBase 的索引有局部索引和全局索引。局部索引和全局索引的索引差別在哪裡?下面通過實戰例子示範如何給 OceanBase 做優化。 閱讀時注意以下幾個優化關鍵參考名額。

  • is_index_back:表示查詢 SQL 是否已經回表,數值是 off 是最好。
  • is_global_index:表示是否已經激活全局索引。
  • physical_range_rows:表示讀取的實體範圍行,數值越小越好。
  • logical_range_rows 表示讀取的邏輯範圍行,數值越小越好。
  • Plan type :有 3 個選項,最優是 LOCAL 對應本地調用,REMOTE 對應遠端調用,最壞情況是 DISTRIBUTED。

準備環境

建一個 user1 表并填充一些資料。

CREATE TABLE `user1` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  `phone` int(12) DEFAULT NULL,
  `address` varchar(100) DEFAULT NULL
) partition by hash(id+1) partitions 3;
obclient [tpch]> select count(*) from  user1
    -> ;
+----------+
| count(*) |
+----------+
|    79993 |
+----------+
1 row in set (0.025 sec)


delimiter //
create procedure bulk_user()
begin
declare i int;
declare phone int;
 set i=100000;
 set phone=1592014273;
 while i<1000001 do
   insert INTO user (id,name ,phone,address) values (i,'yang',phone+i,'address');
 set i=i+1;
 end while;
end
//
delimiter ;
           

索引使用場景

場景一:沒有加索引

obclient [tpch]> explain extended  select phone ,name  from  user1 where   phone = 1592014286;
           
OceanBase 全局索引與局部索引探索
OceanBase 全局索引與局部索引探索

索引測試,沒有加索引前,對全盤進行掃描找到了目标對象,操作過程中産生沒有産生回表。

場景二:加了局部索引

obclient [tpch]> create index idx_user1_phone on user1 (phone) local;
Query OK, 0 rows affected (3.152 sec)

explain extended select phone,name from user1 where phone = 1592014286;
           
OceanBase 全局索引與局部索引探索
OceanBase 全局索引與局部索引探索

索引測試,加了局部索引後,對硬碟掃描隻查找了 791 行,操作過程中居然産生了回表操作。

場景三:分區查找

obclient [tpch]> explain extended select name, phone  from user1  where  id= 5000;
           
OceanBase 全局索引與局部索引探索
OceanBase 全局索引與局部索引探索

分區測試,通過分區為關鍵字查找,按劃分的分區【26664】查找,由于沒有索引設定,周遊所有的 26664,沒有産生回表。

場景四:分區加索引進行查找

obclient [tpch]>  create index idx_user1_id on user1 (id) local;
Query OK, 0 rows affected (3.379 sec)
obclient [tpch]> explain extended select name, phone  from user1  where  id= 5000;
           
OceanBase 全局索引與局部索引探索
OceanBase 全局索引與局部索引探索

分區加索引測試,id 即是索引也是分區。設定索引後按劃分的分區【26664】查找,physical_range_rows 和 logical_range_rows 成績喜人,但是發生回表的操作。

為什麼産生回表?主要語句有 select name, phone, id 是雖然做了索引,但 name 和 phone 是投影,進而做了回表。

場景五:建立唯一索引消滅回表

obclient [tpch]> create  unique index  idx_user_phone_name  on  user1 (phone,name) local ;
ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning function

提示 1503 錯誤,建立唯一索引必須指定分區的指定

obclient [tpch]> create  unique index  idx_user_id_phone_name  on  user1 (phone,name,id) local ;
Query OK, 0 rows affected (3.352 sec)

explain extended  select phone ,name  from  user1 where   phone = 1592014286;
           
OceanBase 全局索引與局部索引探索
OceanBase 全局索引與局部索引探索

為什麼唯一索引必須内含内含分區 ID,必須是唯一性,必須包括主鍵列,基于局部索引加上唯一索引,不産生回表。

場景六:建立全局索引消滅回表

create unique index   global_idx_phone  on  user1(phone,name) global ;

explain extended  select phone ,name  from  user1 where   phone = 1592014286;
           
OceanBase 全局索引與局部索引探索
OceanBase 全局索引與局部索引探索

全局索引按照 phone,name 也可以消來回表。

總結

OceanBase 是單體分布式架構的資料庫,調優第一原則遵從先單體再分布的特色,簡而言之最好内循環把單機性能用光,再外循環使用分布式,力争 LOCAL 優先、REMOTE 為次、DISTRUBTE 是最壞的,綜合執行狀況要結合掃描資料範圍和回表狀況來看。

局部索引應用于争取 LOCAL 的場景,避免 DISTRUBTE。場景二、場影三、場影四 使用 LOCAL,但是場景五使用 DISTRUBTE。深思的是必須結合分區鍵才能完成唯一索引建立。這裡内部的邏輯,局部索引要完成跨域,必須要與分區鍵綁定。

全局索引也可以實作 LOCAL 的場景,見場景六。筆者後續會做 OceanBase 的分布式環境。假設是分布式環境兼資料多的業務場景下,筆者揣測 DISTRUBTE 的機會性較大。

更多技術文章,請通路:https://opensource.actionsky.com/