53倍性能提升!TiDB 全局索引如何優化分區表查詢?

作者: Defined2014 原文來源: https://tidb.net/blog/7077577f

什么是 TiDB 全局索引

在 TiDB 中,全局索引是一種定義在分區表上的索引類型,它允許索引分區與表分區之間建立一對多的映射關系,即一個索引分區可以對應多個表分區。這與 TiDB 早期版本中的本地索引(Local Index)不同,本地索引的索引分區與表分區之間是一對一的映射關系,即一個分區對應一個局部的索引塊。

全局索引能覆蓋整個表的數據,使得主鍵和唯一鍵在不包含分區鍵的情況下仍能保持全局唯一性。此外,全局索引可以在一次操作中訪問多個分區的索引數據,而無需對每個分區的本地索引逐一查找,顯著提升了針對非分區鍵的查詢性能。

下圖簡單展示了本地索引和全局索引的區別

image.png

TiDB 全局索引的發展歷程

  • v7.6.0 版本之前 :TiDB 僅支持分區表的本地索引。這意味著,對于分區表上的唯一鍵,必須包含表分區表達式中的所有列。如果查詢條件中沒有使用分區鍵,那么查詢將不得不掃描所有分區,這會導致查詢性能下降。
  • v7.6.0 版本 :引入了系統變量 tidb_enable_global_index ,用于開啟全局索引功能。然而,當時該功能仍在開發中,不推薦用戶啟用。
  • v8.3.0 版本 :全局索引功能作為實驗性特性發布。用戶可以通過在創建索引時顯式使用 GLOBAL 關鍵字來創建全局索引。
  • v8.4.0 版本 :全局索引功能正式成為一般可用(GA)特性。用戶可以直接使用 GLOBAL 關鍵字創建全局索引,而無需再設置系統變量 tidb_enable_global_index 。從這個版本開始,該系統變量被棄用,并且始終為 ON
  • v8.5.0 版本 :全局索引功能支持了包含分區表達式中的所有列。
  • v9.0.0 版本 :全局索引功能支持了非唯一索引的情況。在分區表中,除聚簇索引外都可以被創建為全局索引。

TiDB 全局索引的語法

在 TiDB 中,創建全局索引(Global Index)時,可以在 CREATE INDEX ALTER TABLE 語句中使用 GLOBAL 關鍵字,或在建表時通過 GLOBAL 關鍵字或 /*T![global_index] GLOBAL */ 注釋指定。

創建全局索引的語法:

CREATE [UNIQUE] INDEX index_name ON table_name (column_list) [GLOBAL];
ALTER TABLE table_name ADD [UNIQUE] INDEX index_name (column_list) [GLOBAL];

示例:

  1. 創建全局唯一索引:
CREATE UNIQUE INDEX idx_global ON employees (email) GLOBAL;

此語句在 employees 表的 email 列上創建一個全局唯一索引,確保每個電子郵件地址在整個表中唯一。

  1. 添加全局索引:
ALTER TABLE orders ADD INDEX idx_global_order_date (order_date) GLOBAL;

此語句向 orders 表添加一個名為 idx_global_order_date 的全局索引,索引列為 order_date

  1. 在建表時創建全局索引:
CREATE TABLE `sbtest` (`id` int NOT NULL,`k` int NOT NULL DEFAULT '0',`c` char NOT NULL DEFAULT '',KEY `idx1` (`k`) GLOBAL,KEY `idx2` (`k`) /*T![global_index] GLOBAL */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY HASH (`id`) PARTITIONS 5;

此語句在創建 sbtest 表時同時創建了兩個名為 idx1 idx2 的全局索引,兩個索引的索引列都為 k

TiDB 全局索引的優勢

提升查詢性能

全局索引能夠有效提高檢索非分區列的效率。當查詢涉及非分區列時,全局索引可以快速定位相關數據,避免了對所有分區的全表掃描,可以顯著降低 cop task 的數量,這對于分區數量龐大的場景尤為有效。

經過測試,在分區數量為 100 的情況下,sysbench select_random_points 場景得到了 53 倍 的性能提升。

增強應用靈活性

全局索引的引入,消除了分區表上唯一鍵必須包含所有分區列的限制。這使得用戶在設計索引時更加靈活,可以根據實際的查詢需求和業務邏輯來創建索引,而不再受限于表的分區方案。這種靈活性有助于更好地優化查詢性能,滿足多樣化的業務需求。

減少應用修改工作量

在數據遷移和應用修改過程中,全局索引可以減少對應用的修改工作量。如果沒有全局索引,在遷移數據或修改應用時,可能需要調整分區方案或重寫查詢語句以適應索引的限制。有了全局索引之后,這些修改可以被避免,從而降低了開發和維護成本。

如在將 Oracle 數據庫中的某張表遷移到 TiDB 時,因為 Oracle 支持全局索引,可能在某些表上存在一些不包含分區列的唯一索引,在遷移過程需要對表結構進行調整,以適應 TiDB 的分區表限制。然而,隨著 TiDB 對全局索引的支持,用戶只需簡單地修改索引定義,將其設置為全局索引,即可與 Oracle 保持一致,從而顯著降低遷移成本。

TiDB 全局索引的工作原理

基本思想

在 TiDB 的分區表中,本地索引的鍵值前綴是分區表的 ID 而全局索引的前綴是表的 ID。這樣的改動確保了全局索引的數據在 TiKV 上分布是連續的,降低了查詢索引時 RPC 的數量。

CREATE TABLE `sbtest` (`id` int(11) NOT NULL,`k` int(11) NOT NULL DEFAULT '0',`c` char(120) NOT NULL DEFAULT '',KEY idx(k),KEY global_idx(k) GLOBAL
) partition by hash(id) partitions 5;

以上面的表結構為例, idx 為普通索引, global_idx 為全局索引。索引 idx 的數據會分布在 5 個不同的 ranges 中,如 PartitionID1_i_xxx , PartitionID2_i_xxx 等,而索引 global_idx 的數據則會集中在一個 range ( TableID_i_xxx ) 內。

這樣當我們進行 k 相關的查詢時,如 select * from sbtest where k > 1 ,通過索引 idx 會構造 5 個不同的 ranges,而通過全局索引 global_idx 則只會構造 1 個 range,每個 range 在 TiDB 中對應一個或多個 RPC 請求,這樣使用全局索引可以降低數倍的 RPC 請求數,從而提升查詢索引的性能。

下圖更加直觀地展示了在使用 idx global_idx 兩個不同索引執行 select * from sbtest where k > 1 查詢語句在 RPC 請求和數據流轉過程中的差異。

image.png

編碼方式

在 TiDB 中,索引項被編碼為鍵值對。對于分區表,每個分區在 TiKV 層被視為一個獨立的物理表,擁有自己的 partitionID 。因此,分區表的索引項也被編碼為:

唯一鍵
Key:
- PartitionID_indexID_ColumnValuesValue:
- IntHandle- TailLen_IntHandle- CommonHandle- TailLen_IndexVersion_CommonHandle非唯一鍵
Key:
- PartitionID_indexID_ColumnValues_HandleValue:
- IntHandle- TailLen_Padding- CommonHandle- TailLen_IndexVersion

在全局索引中,索引項的編碼方式有所不同。為了使全局索引的鍵布局與當前索引鍵編碼保持兼容,新的索引編碼布局為:

唯一鍵
Key:
- TableID_indexID_ColumnValuesValue:
- IntHandle- TailLen_PartitionID_IntHandle- CommonHandle- TailLen_IndexVersion_CommonHandle_PartitionID非唯一鍵
Key:
- TableID_indexID_ColumnValues_HandleValue:
- IntHandle- TailLen_PartitionID- CommonHandle- TailLen_IndexVersion_PartitionID

這種編碼方式使得全局索引的鍵以 TableID 開頭,而 PartitionID 被放置在 Value 中。這樣設計的優點是,它與現有的索引鍵編碼方式兼容,但同時也帶來了一些挑戰,例如在執行 DROP PARTITION, TRUNCATE PARTITION 等 DDL 操作時,由于索引項不連續,需要進行額外的處理。

TiDB 全局索引的限制與注意事項

影響部分 DDL 性能

當分區表中存在全局索引時,執行諸如 DROP PARTITION(刪除分區)、TRUNCATE PARTITION(清空分區)、REORG PARTITION(重組分區)等部分 DDL 操作時,需要同步更新全局索引的值,這會顯著增加 DDL 操作的執行時間。

在 v8.5.0 默認參數下,測試顯示對包含全局索引的 sysbench 表執行 DROP PARTITION 或 TRUNCATE PARTITION 操作時, oltp_read_write 負載的性能會下降 15% 至 20%。

聚簇索引 (Clustered Index)

聚簇索引不能成為全局索引,是因為如果聚簇索引是全局索引,則表將不再分區。這是因為聚簇索引的鍵是分區級別的行數據的鍵,但全局索引是表級別的,這就造成了沖突。如果需要將主鍵設置為全局索引,則需要顯式設置該主鍵為非聚簇索引,如 PRIMARY KEY(col1, col2) NONCLUSTERED GLOBAL

性能測試數據

  • select_random_points in sysbench

示例表結構

CREATE TABLE `sbtest` (`id` int(11) NOT NULL,`k` int(11) NOT NULL DEFAULT '0',`c` char(120) NOT NULL DEFAULT '',`pad` char(60) NOT NULL DEFAULT '',PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,KEY `k_1` (`k`)/* Key `k_1` (`k`, `c`) GLOBAL */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
/* Partition by hash(`id`) partitions 100 */
/* Partition by range(`id`) xxxx */

負載 SQL

SELECT id, k, c, pad
FROM sbtest1
WHERE k IN (xx, xx, xx)
Range Partition (100 partitions)
Concurrency 1 32 64 Average RU
Clustered non-partitioned table 225 19,999 30,293 7.92
Clustered table range partitioned by PK 68 480 511 114.87
Clustered table range partitioned by PK, with Global Index on k, c columns 207 17,798 27,707 11.73
Hash Partition (100 partitions)
Concurrency 1 32 64 Average RU
Clustered non-partitioned table 166 20361 28922 7.86
Clustered table hash partitioned by PK 60 244 283 119.73
Clustered table hash partitioned by PK, with Global Index on k, c columns 156 18233 15581 10.77
  • 通過上述測試可以看出,在高并發環境下,全局索引能夠顯著提升分區表查詢性能,提升幅度可達 50 倍。同時,全局索引還能夠顯著降低資源(RU)消耗。隨著分區數量的增加,這種性能提升的效果將愈加明顯。

最佳實踐

全局索引和本地索引

全局索引適用場景

  • 數據歸檔不頻繁 :例如,醫療行業的部分業務數據需要保存 30 年,通常按月分區,然后一次性創建 360 個分區,且很少進行 DROP TRUNCATE 操作。在這種情況下,使用全局索引更為合適,因為它能提供跨分區的一致性和查詢性能。
  • 查詢需要跨分區的數據 :當查詢需要訪問多個分區的數據時,全局索引可以避免跨分區掃描,提高查詢效率。

本地索引適用場景

  • 數據歸檔需求 :如果數據歸檔操作很頻繁,且主要查詢集中在單個分區內,本地索引可以提供更好的性能。
  • 需要使用分區交換功能 :在銀行等行業,可能會將處理后的數據先寫入普通表,確認無誤后再交換到分區表,以減少對分區表性能的影響。此時,本地索引更為適用,因為在使用了全局索引之后,分區表將不再支持分區交換功能。

全局索引和聚簇索引

由于聚簇索引和全局索引的原理限制,一個索引不能同時作為聚簇索引和全局索引。然而,這兩種索引在不同查詢場景中能提供不同的性能優化。在遇到需要同時兼顧兩者的需求時,我們可以將分區列添加到聚簇索引中,同時創建一個不包含分區列的全局索引。

假設我們有如下表結構:

CREATE TABLE `t` (`id` int DEFAULT NULL,`ts` timestamp NULL DEFAULT NULL,`data` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY RANGE (UNIX_TIMESTAMP(`ts`))
(PARTITION `p0` VALUES LESS THAN (1735660800)PARTITION `p1` VALUES LESS THAN (1738339200)...)

在上面的 t 表中, id 列的值是唯一的。為了優化點查和范圍查詢的性能,我們可以選擇在建表語句中定義一個聚簇索引 PRIMARY KEY(id, ts) 和一個不包含分區列的全局索引 UNIQUE KEY id(id) 。這樣在進行基于 id 的點查詢時,會走全局索引 id ,選擇 PointGet 的執行計劃;而在進行范圍查詢時,聚簇索引則會被選中,因為聚簇索引相比全局索引少了一次回表操作,從而提升查詢效率。

修改后的表結構如下所示:

CREATE TABLE `t` (`id` int NOT NULL,`ts` timestamp NOT NULL,`data` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`, `ts`) /*T![clustered_index] CLUSTERED */,UNIQUE KEY `id` (`id`) /*T![global_index] GLOBAL */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY RANGE (UNIX_TIMESTAMP(`ts`))
(PARTITION `p0` VALUES LESS THAN (1735660800),PARTITION `p1` VALUES LESS THAN (1738339200)...)

通過這種方式,我們既能優化基于 id 的點查詢,又能提升范圍查詢的性能,同時確保表的分區列在基于時間戳的查詢中能得到有效的利用。

總結

TiDB 全局索引是 TiDB 在分區表索引方面的重要特性,它通過允許索引分區與表分區之間提供一對多的映射關系,提供了更靈活的索引設計和更高效的查詢性能。全局索引的引入,不僅提升了 TiDB 分區表在處理復雜查詢和大數據量場景下的能力,還為用戶在數據庫設計和優化方面提供了更多的選擇。

然而,全局索引也帶來了一些挑戰,如維護成本的增加。在使用全局索引時,需要根據具體的業務需求和數據特點,合理設計索引,權衡查詢性能和數據修改性能,以達到最佳的數據庫性能。

總之,TiDB 全局索引是一個強大且靈活的特性,能夠幫助用戶更好地優化數據庫性能,滿足多樣化的業務需求。在實際應用中,合理使用全局索引,可以顯著提升查詢性能,提高數據庫的整體效率。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/895562.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895562.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895562.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

排序(Sortable)

排序(Sortable) 引言 在計算機科學和數據管理領域,排序算法是一項基本且重要的技能。排序算法能夠將一組無序的數據轉換為有序的數據,從而便于后續的數據處理和分析。本文將深入探討排序算法的基本概念、常用排序方法、以及它們…

紫光展銳蜂窩物聯網芯片V8850榮獲國密一級安全認證

近日,紫光展銳蜂窩物聯網芯片V8850榮獲國密一級認證,標志著展銳V8850在安全能力方面獲得權威認可,位居行業領先水平。這是紫光展銳繼短距物聯網芯片V5663在2020獲得ARM PSA Level 2認證,蜂窩物聯網芯片V8811在2021年獲得ARM PSA L…

I.MX6ull-I2C

一,I2C總線介紹 I2C(Inter-Integrated Circuit 集成電路)總線是Philips公司在八十年代初推出的一種串行、半雙工的總 線,主要用于近距離、低速的芯片之間的通信;I2C總線有兩根雙向的信號線,一根數據線SDA用于收 發數據,一根時鐘線…

書籍推薦:《書法課》林曦

記得樊登老師說過,如果你想了解一個事物,就去讀5本相關的書,你會比大部分人都更了解它。這是我讀的第4本和“書法”有關的書,作為一個零基礎的成年人,林曦這本《書法課》非常值得一讀。(無論你是否寫字&…

【大疆無人機地圖測繪技術學習:高精度、高效率的全流程解決方案】

文章目錄 大疆無人機地圖測繪算法詳解一、數據采集(一)飛行平臺與傳感器(二)航線規劃(三)數據類型 二、數據處理與建模(一)數據導入與預處理(二)空三計算&…

【刪除tomcat默認管理控制臺】

停止Tomcat: ./catalina.sh stop 刪除管理控制臺應用: 進入Tomcat的webapps目錄: cd /path/to/tomcat/webapps List item 刪除manager和host-manager文件夾: rm -rf manager host-manager 啟動Tomcat: ./catali…

工具資料+H3C 交換機常見故障分析排查+高危操作

當我們從客戶那里接到一個故障時,我們根據現象讓客戶收集一堆信息,然后集成商、代理商、設備廠家一級一級的反復咨詢與確認,天天經歷這樣的場景。幾乎每個故障我們都要經過多個層級的人處理,信息的交流占據了每個人大部分的時間,反復的收集信息與確認問題現象也會讓客戶不厭其煩…

STM32:USB 虛擬串口以及使用usb->dfu進行iap

本文介紹stm32上usb的常用功能虛擬串口和DFU(Download Firmware Update) 文章目錄 前言一、usb二、虛擬串口1.cubemx配置1.我們選用高速usb,然后選擇內部低速的phy,這樣使用的usb,最高速度為12Mbit每秒。2.USB_DEVICE cdc類配置3.時鐘配置&am…

HCIA項目實踐--靜態路由的綜合實驗

八 靜態路由綜合實驗 (1)劃分網段 # 192.168.1.0 24#分析:每個路由器存在兩個環回接口,可以把兩個環回接口分配一個環回地址,所以是四個環回,一個骨干,這樣分配,不會出現路由黑洞#19…

C++基礎知識(三)之結構體、共同體、枚舉、引用、函數重載

九、結構體、共同體和枚舉 1、結構體的基本概念 結構體是用戶自定義的類型,可以將多種數據的表示合并到一起,描述一個完整的對象。 使用結構體有兩個步驟:1)定義結構體描述(類型);2&#xff…

通過內網穿透ssh實現遠程對家里的linux進行終端操作和編程

內網穿透就是將自己的地址當穿透到公網ip,這一就可以在外網訪問了(因為大部分人ip都是動態分配的),以適用ssh遠程連接,我這里用的是極點云cpolar,反正也是黑框編程,免費就行了。我是ubuntu虛擬機,在虛擬機上…

Redis 數據類型 Zset 有序集合

有序集合相對于字符串、列表、哈希、集合來說會有?些陌?。它保留了集合不能有重復成員的特點,但與集合不同的是,有序集合中的每個元素都有?個唯?的浮點類型的分數(score)與之關 聯,著使得有序集合中的元素是可以維…

PHP 中的除以零錯誤

除以零錯誤(Division by zero)是指數字除以零的情況, 這在數學上是未定義的。在 PHP 中,處理這種錯誤的方式取決于 PHP 版本: PHP 7: 使用 / 運算符會產生一個警告 (E_WARNING) 并返回 false。 使用 intd…

基于springboot軌道交通安全評估系統(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 時代在飛速進步,每個行業都在努力發展現在先進技術,通過這些先進的技術來提高自己的水平和優勢,軌道交通安全評估管理當然不能排除在外。軌道交通安全評估系統是在實際應用和軟件工程的開發原理之上,運用Java語言以及Spring…

前端面試題目---頁面抖動的原因、如何避免、如何解決

前端頁面抖動是一個常見且影響用戶體驗的問題,下面將從抖動發生的場景、解決辦法以及預防措施三個方面進行詳細闡述。 頁面抖動發生的場景 1. 元素尺寸動態變化 圖片加載:當頁面中圖片的寬高沒有預先設定,在圖片加載完成后,其實…

vue知識點3

1.使用componenent的好處 符合高內聚,低耦合。一個組件出問題了,不會影響其他組件。 2.vue版本決定了一些使用框架的版本 vue2使用的路由版本只能到3 3.路由的配置介紹一下 a.安裝路由的插件 npm install vue-router3 b.整理文件路徑 將路徑整理…

如何測試和驗證CVE-2024-1430:Netgear R7000 路由器信息泄露漏洞分析

CVE-2024-1430 是一個影響 Netgear R7000 路由器的安全漏洞,漏洞來源于該路由器 Web 管理界面的信息泄露問題。攻擊者通過訪問 /currentsetting.htm 文件,可能泄露敏感信息,如 Wi-Fi 密碼等。 在測試和驗證 CVE-2024-1430 時,您需…

數據結構:哈夫曼樹

1.概念 哈夫曼樹(Huffman Tree)是一種用于數據壓縮的二叉樹,由大衛哈夫曼(David A. Huffman)于1952年提出。它通過構建最優二叉樹來實現數據的高效壓縮,廣泛應用于文件壓縮、圖像壓縮等領域。 哈夫曼樹的…

UE5.2后 Bake Out Materials失效

這個問題出現在5.3,5.4,5.5沒有測試 烘焙貼圖后會找不到貼圖位置, 這個是5.2的正常狀態 默認是生成在模型當前目錄里,包括新的材質 但是這個bug會讓材質和貼圖都消失,無法定位 暫時沒有辦法解決,等官方 …

ADC 的音頻實驗,無線收發模塊( nRF24L01)

nRF24L01 采用 QFN20 封裝,有 20 個引腳,以下是各引腳的詳細介紹: 1. 電源引腳 ? VDD:電源輸入端,一般接 3V 電源,為芯片提供工作電壓,供電電壓范圍為 1.9V~3.6V。 ? VSS&#xf…