KingbaseES數(shù)據(jù)庫(kù)中索引和并行查詢(xún)的SQL優(yōu)化方法實(shí)戰(zhàn)指南
前言
在數(shù)據(jù)庫(kù)應(yīng)用中,SQL語(yǔ)句的性能直接決定了系統(tǒng)的響應(yīng)速度和吞吐量。KingbaseES作為一款高度兼容Oracle的企業(yè)級(jí)數(shù)據(jù)庫(kù),提供了豐富的SQL優(yōu)化手段。下面我們就從索引優(yōu)化、HINT使用、參數(shù)調(diào)整、并行查詢(xún)等核心維度,帶您掌握實(shí)戰(zhàn)化的SQL優(yōu)化技巧,附代碼示例和操作建議。
一、索引優(yōu)化:提升查詢(xún)效率的基石
索引是一種有序的存儲(chǔ)結(jié)構(gòu),也是一項(xiàng)極為重要的SQL 優(yōu)化手段,可以提高數(shù)據(jù)檢索的速度。通過(guò)在表中的一個(gè)或多個(gè)列上創(chuàng)建索引,很多SQL語(yǔ)句的執(zhí)行效率可以得到極大的提高。

1.1 主流索引類(lèi)型及適用場(chǎng)景
KingbaseES提供8種索引類(lèi)型,不同類(lèi)型對(duì)應(yīng)不同查詢(xún)需求,核心類(lèi)型及應(yīng)用場(chǎng)景如下表所示:
| 索引類(lèi)型 | 核心原理 | 適用場(chǎng)景 | 支持操作符 |
|---|---|---|---|
| Btree索引 | 基于B+樹(shù)結(jié)構(gòu),有序存儲(chǔ) | 范圍查詢(xún)、排序(ORDER BY/MIN/MAX)、等值查詢(xún) | >、<、>=、<=、=、IN、LIKE(前匹配) |
| Hash索引 | 哈希表映射,快速定位等值數(shù)據(jù) | 僅等值查詢(xún)(=),不支持范圍查詢(xún) | = |
| Bitmap索引 | 位圖存儲(chǔ),用bit位標(biāo)記數(shù)據(jù)存在性 | 低基數(shù)列(如性別、狀態(tài))、多條件組合查詢(xún)(AND/OR) | =、IN |
| GIN索引 | 通用倒排索引,存儲(chǔ)(關(guān)鍵詞+位置)映射 | 數(shù)組、全文檢索、多值字段查詢(xún) | @@(全文匹配)、@>(包含) |
| BRIN索引 | 塊范圍索引,存儲(chǔ)數(shù)據(jù)塊的取值范圍 | 有序數(shù)據(jù)(如時(shí)間序列日志),數(shù)據(jù)塊內(nèi)值連續(xù) | >、<、>=、<= |

代碼示例:Btree索引優(yōu)化范圍查詢(xún)
Btree 是索引是最常見(jiàn)的索引類(lèi)型,也是 KingbaseES 的默認(rèn)索引,采用 B+ 樹(shù) (N 叉排序樹(shù)) 實(shí)現(xiàn),由于樹(shù)狀結(jié)構(gòu)每一層節(jié)點(diǎn)都有序列,因此非常適合用來(lái)做范圍查詢(xún)和優(yōu)化排序操作。Btree索引支持的操作符有>,<,>=,<=,=,IN,LIKE 等,同時(shí),優(yōu)化器也會(huì)優(yōu)先選擇Btree來(lái)對(duì)ORDERBY、MIN\MAX、MERGEJOIN進(jìn)行有序操作
-- 創(chuàng)建測(cè)試表
CREATE TABLE t_orders (
order_id INT,
order_time TIMESTAMP,
amount NUMERIC(10,2)
);
-- 插入100萬(wàn)條測(cè)試數(shù)據(jù)
INSERT INTO t_orders
VALUES (generate_series(1,1000000),
CURRENT_TIMESTAMP - (random()*365)::INT,
random()*1000);
-- 無(wú)索引時(shí)查詢(xún):全表掃描,耗時(shí)較長(zhǎng)
EXPLAIN ANALYZE
SELECT * FROM t_orders WHERE order_time > '2024-01-01';
-- 執(zhí)行結(jié)果:Seq Scan on t_orders (cost=0.00..22000.00 rows=300000 width=20) (actual time=0.03..500.12 ms)
-- 創(chuàng)建Btree索引
CREATE INDEX idx_orders_time ON t_orders USING btree(order_time);
-- 有索引時(shí)查詢(xún):索引掃描,耗時(shí)顯著降低
EXPLAIN ANALYZE
SELECT * FROM t_orders WHERE order_time > '2024-01-01';
-- 執(zhí)行結(jié)果:Index Scan using idx_orders_time on t_orders (cost=0.43..8000.00 rows=300000 width=20) (actual time=0.05..80.36 ms)
1.2 索引使用實(shí)戰(zhàn)技巧
表達(dá)式索引:解決函數(shù)/計(jì)算導(dǎo)致的索引失效
當(dāng)查詢(xún)條件包含函數(shù)或表達(dá)式時(shí)(如upper(name)),普通索引無(wú)法生效,需創(chuàng)建表達(dá)式索引:
-- 創(chuàng)建表達(dá)式索引(忽略大小寫(xiě)查詢(xún)) CREATE INDEX idx_emp_upper_name ON emp (upper(ename)); -- 查詢(xún)時(shí)直接使用表達(dá)式,觸發(fā)索引 EXPLAIN ANALYZE SELECT * FROM emp WHERE upper(ename) = 'SMITH';
聯(lián)合索引:遵循“最左前綴原則”
聯(lián)合索引是在建立在某個(gè)關(guān)系表上多列的索引,也叫復(fù)合索引。創(chuàng)建聯(lián)合索引時(shí),應(yīng)該將最常被訪問(wèn)的列放在索引列表前面。當(dāng)where子句中引用了聯(lián)合索引中的所有列,或者前導(dǎo)列,聯(lián)合索引可以加快檢索速度。
-- 創(chuàng)建聯(lián)合索引(order_time過(guò)濾性強(qiáng),放在左側(cè)) CREATE INDEX idx_orders_time_amount ON t_orders (order_time, amount); -- 有效查詢(xún):命中聯(lián)合索引(使用前導(dǎo)列order_time) SELECT * FROM t_orders WHERE order_time > '2024-01-01' AND amount > 500; -- 無(wú)效查詢(xún):未使用前導(dǎo)列,無(wú)法命中索引 SELECT * FROM t_orders WHERE amount > 500;
Like模糊查詢(xún)優(yōu)化:按匹配方式選擇索引
- 前匹配(如
'abc%'):使用Btree索引(需指定text_pattern_ops); - 后匹配(如
'%abc'):通過(guò)reverse()函數(shù)轉(zhuǎn)換為前匹配; - 中間匹配(如
'%abc%'):使用TRGM索引(依賴(lài)sys_trgm插件)。
-- 1. 前匹配:Btree索引
CREATE INDEX idx_emp_name_pattern ON emp (ename text_pattern_ops);
SELECT * FROM emp WHERE ename LIKE 'SM%';
-- 2. 后匹配:reverse()表達(dá)式索引
CREATE INDEX idx_emp_name_reverse ON emp (reverse(ename) collate "C");
SELECT * FROM emp WHERE reverse(ename) LIKE reverse('%ITH'); -- 等價(jià)于ename LIKE '%ITH'
-- 3. 中間匹配:TRGM索引
CREATE EXTENSION sys_trgm; -- 啟用插件
CREATE INDEX idx_emp_name_trgm ON emp USING gin(ename gin_trgm_ops);
SELECT * FROM emp WHERE ename LIKE '%MIT%';
定期維護(hù)索引:避免索引膨脹
刪除長(zhǎng)期未使用的索引,定期執(zhí)行VACUUM和索引重建,解決索引頁(yè)面稀疏問(wèn)題:
-- 查看索引使用情況(idx_scan為0表示未使用) SELECT relname AS 表名, indexrelname AS 索引名, idx_scan AS 掃描次數(shù) FROM sys_stat_user_indexes ORDER BY idx_scan; -- 重建索引(優(yōu)化索引結(jié)構(gòu)) REINDEX INDEX idx_orders_time; -- 全表VACUUM(釋放刪除數(shù)據(jù)的空間,確保覆蓋索引生效) VACUUM ANALYZE t_orders;
二、HINT:手動(dòng)干預(yù)執(zhí)行計(jì)劃
KingbaseES使用的是基于成本的優(yōu)化器。優(yōu)化器會(huì)估計(jì)SQL語(yǔ)句的每個(gè)可能的執(zhí)行計(jì)劃的成本,然后選擇成本最低的執(zhí)行計(jì)劃來(lái)執(zhí)行。因?yàn)閮?yōu)化器不計(jì)算數(shù)據(jù)的某些屬性,比如列之間的相關(guān)性,優(yōu)化器有時(shí)選擇的計(jì)劃并不一定是最優(yōu)的。
2.1 核心HINT類(lèi)型及用法
KingbaseES支持多種HINT,常用類(lèi)型及示例如下:
| HINT類(lèi)型 | 功能 | 示例 |
|---|---|---|
| 掃描類(lèi)型HINT | 指定表的掃描方式(如索引掃描、順序掃描) | /*+IndexScan(t_orders idx_orders_time)*/ |
| 連接類(lèi)型HINT | 強(qiáng)制兩表連接算法(嵌套循環(huán)、哈希連接等) | /*+HashJoin(t_orders t_customers)*/ |
| 連接順序HINT | 指定多表連接順序 | /*+leading((t_customers t_orders) t_products)*/ |
| 并行HINT | 開(kāi)啟并行查詢(xún)及worker進(jìn)程數(shù) | /*+Parallel(t_orders 4)*/ |
| ROWS HINT | 修正優(yōu)化器對(duì)結(jié)果行數(shù)的估算 | /*+rows(t_orders #1000)*/(強(qiáng)制估算為1000行) |
2.2 實(shí)戰(zhàn)示例:HINT優(yōu)化多表連接
假設(shè)t_orders(100萬(wàn)行)與t_customers(10萬(wàn)行)連接查詢(xún),優(yōu)化器誤選嵌套循環(huán)連接(適合小表),需強(qiáng)制哈希連接:
-- 原始查詢(xún):優(yōu)化器選擇Nested Loop,耗時(shí)較長(zhǎng) EXPLAIN ANALYZE SELECT o.order_id, c.cust_name FROM t_orders o JOIN t_customers c ON o.cust_id = c.cust_id WHERE o.order_time > '2024-01-01'; -- 使用HINT強(qiáng)制HashJoin,提升效率 EXPLAIN ANALYZE SELECT /*+HashJoin(o c)*/ o.order_id, c.cust_name FROM t_orders o JOIN t_customers c ON o.cust_id = c.cust_id WHERE o.order_time > '2024-01-01';
2.3 注意事項(xiàng)
- 啟用HINT需先配置
kingbase.conf:enable_hint = on; - HINT僅作用于當(dāng)前SQL,避免全局修改參數(shù)影響其他查詢(xún);
- 優(yōu)先通過(guò)更新統(tǒng)計(jì)信息(
ANALYZE)解決計(jì)劃問(wèn)題,HINT作為補(bǔ)充手段。
三、性能參數(shù)調(diào)整:優(yōu)化數(shù)據(jù)庫(kù)資源分配
通過(guò)調(diào)整KingbaseES的核心參數(shù),可適配硬件環(huán)境和業(yè)務(wù)負(fù)載,提升SQL執(zhí)行效率。
3.1 核心參數(shù)分類(lèi)及優(yōu)化建議
成本參數(shù):匹配硬件性能
優(yōu)化器內(nèi)部使用基于成本的算法來(lái)獲取總成本最低的訪問(wèn)路徑。在計(jì)算成本的公式中,會(huì)用到一些定義好的參數(shù)因子,這些參數(shù)因子會(huì)影響到最終計(jì)算出出來(lái)的總成本。
成本參數(shù)決定優(yōu)化器對(duì)I/O和CPU代價(jià)的評(píng)估,需根據(jù)硬件配置調(diào)整:
-- 1. 磁盤(pán)I/O優(yōu)化(SSD磁盤(pán)可降低隨機(jī)讀成本) SET random_page_cost = 2.0; -- 默認(rèn)4.0,SSD建議2.0-3.0 SET seq_page_cost = 0.5; -- 默認(rèn)1.0,SSD建議0.5-1.0 -- 2. CPU性能優(yōu)化(高性能CPU可降低CPU代價(jià)系數(shù)) SET cpu_tuple_cost = 0.005; -- 默認(rèn)0.01,CPU強(qiáng)可調(diào)至0.005 SET cpu_operator_cost = 0.001; -- 默認(rèn)0.0025,CPU強(qiáng)可調(diào)至0.001
內(nèi)存參數(shù):避免臨時(shí)文件開(kāi)銷(xiāo)
數(shù)據(jù)比較多大的情況,主要和排序的數(shù)據(jù)有關(guān)系,排序數(shù)據(jù)越大,設(shè)置的就越大,比如 16g內(nèi)存,tpch 測(cè)試,單用戶(hù) 10g 規(guī)模數(shù)據(jù),設(shè)置 2g 的 work_mem。數(shù)值以 kB 為單位的,缺省是1024(1MB)。索引掃描不用 work_mem。
-- 查看當(dāng)前work_mem配置 SHOW work_mem; -- 臨時(shí)調(diào)整work_mem(應(yīng)對(duì)復(fù)雜排序查詢(xún)) SET work_mem = '64MB'; -- 永久配置(kingbase.conf) work_mem = 32MB; -- 默認(rèn)1MB,復(fù)雜查詢(xún)建議32MB-128MB maintenance_work_mem = 256MB; -- 維護(hù)操作(如CREATE INDEX)內(nèi)存,默認(rèn)16MB
并行參數(shù):利用多核CPU
開(kāi)啟并行查詢(xún)可將單條SQL的執(zhí)行任務(wù)分配到多個(gè)CPU核心,適合大數(shù)據(jù)量查詢(xún):
-- 1. 全局并行配置(kingbase.conf) max_worker_processes = 16; -- 最大后臺(tái)進(jìn)程數(shù),建議等于CPU核心數(shù) max_parallel_workers = 8; -- 最大并行worker數(shù) max_parallel_workers_per_gather = 4; -- 單查詢(xún)最大并行worker數(shù) -- 2. 臨時(shí)開(kāi)啟并行查詢(xún)(HINT方式) EXPLAIN ANALYZE SELECT /*+Parallel(t_orders 4)*/ COUNT(*) FROM t_orders WHERE order_time > '2024-01-01';
四、并行查詢(xún):突破單核心性能瓶頸
KingbaseES 能使用多核 CPU 來(lái)加速一個(gè) SQL 語(yǔ)句的執(zhí)行時(shí)間,這種特性被稱(chēng)為并行查詢(xún)。由于現(xiàn)實(shí)條件的限制或因?yàn)闆](méi)有比并行查詢(xún)計(jì)劃更快的查詢(xún)計(jì)劃存在,很多查詢(xún)并不能從并行查詢(xún)獲益。但是,對(duì)于那些可以從并行查詢(xún)獲益的查詢(xún)來(lái)說(shuō),并行查詢(xún)帶來(lái)的速度提升是顯著的。很多查詢(xún)?cè)谑褂貌⑿胁樵?xún)時(shí)查詢(xún)速度比之前快了超過(guò)兩倍,有些查詢(xún)是以前的四倍甚至更多的倍數(shù)。

4.1 并行查詢(xún)適用場(chǎng)景
- 全表掃描或大表索引掃描(數(shù)據(jù)量>8MB,可通過(guò)
min_parallel_table_scan_size調(diào)整); - 哈希連接、歸并連接(多表大數(shù)據(jù)量連接);
- 聚集操作(如
COUNT、SUM,需開(kāi)啟parallel_hashagg)。
4.2 實(shí)戰(zhàn)示例:并行聚集查詢(xún)
-- 創(chuàng)建大表(1000萬(wàn)行)
CREATE TABLE t_sales (
sale_id INT,
sale_date DATE,
amount NUMERIC(10,2)
);
INSERT INTO t_sales
VALUES (generate_series(1,10000000),
CURRENT_DATE - (random()*365)::INT,
random()*2000);
-- 關(guān)閉并行:?jiǎn)芜M(jìn)程執(zhí)行,耗時(shí)較長(zhǎng)
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE
SELECT sale_date, SUM(amount)
FROM t_sales
GROUP BY sale_date;
-- 執(zhí)行結(jié)果:HashAggregate (cost=200000.00..210000.00 rows=365 width=12) (actual time=1500.23..1800.56 ms)
-- 開(kāi)啟并行(4個(gè)worker):多進(jìn)程并行聚集,耗時(shí)降低
SET max_parallel_workers_per_gather = 4;
EXPLAIN ANALYZE
SELECT /*+Parallel(t_sales 4) ParallelHashagg*/
sale_date, SUM(amount)
FROM t_sales
GROUP BY sale_date;
-- 執(zhí)行結(jié)果:Finalize HashAggregate (cost=120000.00..130000.00 rows=365 width=12) (actual time=500.12..600.34 ms)
六、總結(jié)
總的來(lái)說(shuō),KingbaseES 的 SQL 優(yōu)化是一項(xiàng)系統(tǒng)性工程,需結(jié)合業(yè)務(wù)場(chǎng)景靈活運(yùn)用索引優(yōu)化、HINT 干預(yù)、參數(shù)調(diào)整和并行查詢(xún)等多種手段。實(shí)際操作中,通過(guò)執(zhí)行計(jì)劃定位瓶頸后,優(yōu)先用合理建索引等結(jié)構(gòu)性?xún)?yōu)化,再輔以參數(shù)與 HINT 調(diào)優(yōu),同時(shí)定期維護(hù)統(tǒng)計(jì)信息與索引,即可高效應(yīng)對(duì)高并發(fā)、大數(shù)據(jù)量場(chǎng)景。作為高度兼容 Oracle 的企業(yè)級(jí)數(shù)據(jù)庫(kù),KingbaseES 不僅提供豐富且實(shí)用的優(yōu)化工具,還能保障業(yè)務(wù)平滑遷移,是支撐企業(yè)核心系統(tǒng)穩(wěn)定運(yùn)行的可靠選擇。
到此這篇關(guān)于KingbaseES數(shù)據(jù)庫(kù)中索引和并行查詢(xún)的SQL優(yōu)化方法實(shí)戰(zhàn)指南的文章就介紹到這了,更多相關(guān)KingbaseES SQL優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python操作國(guó)產(chǎn)金倉(cāng)數(shù)據(jù)庫(kù)KingbaseES全流程
- Python連接KingbaseES的實(shí)戰(zhàn)指南
- MyBatis-Plus整合金倉(cāng)數(shù)據(jù)庫(kù)KingbaseES的實(shí)戰(zhàn)指南
- Oracle數(shù)據(jù)庫(kù)移植到KingbaseES的全流程
- Ubuntu服務(wù)器安裝與配置KingbaseES國(guó)產(chǎn)數(shù)據(jù)庫(kù)方法(圖文)
- MySQL數(shù)據(jù)庫(kù)遷移到KingbaseES的完整指南
- KingbaseES中的MySQL案例實(shí)戰(zhàn)講解
相關(guān)文章
Maven nexus 安裝nexus私服出現(xiàn)的問(wèn)題和解決辦法
本文主要介紹安裝nexus私服的時(shí)候出現(xiàn)問(wèn)題的解決辦法,這里整理了兩種問(wèn)題并詳細(xì)說(shuō)明了解決辦法,有需要的朋友可以參考下2016-08-08
postgres 數(shù)據(jù)庫(kù)中的數(shù)據(jù)轉(zhuǎn)換
postgres8.3以后,字段數(shù)據(jù)之間的默認(rèn)轉(zhuǎn)換取消了。如果需要進(jìn)行數(shù)據(jù)變換的話,在postgres數(shù)據(jù)庫(kù)中,我們可以用"::"來(lái)進(jìn)行字段數(shù)據(jù)的類(lèi)型轉(zhuǎn)換。2009-07-07
簡(jiǎn)單分析SQLite4的一些設(shè)計(jì)改變
這篇文章主要介紹了SQLite4的一些設(shè)計(jì)改變,SQLite作為內(nèi)嵌式數(shù)據(jù)庫(kù)使用起來(lái)非常輕便,需要的朋友可以參考下2015-07-07
國(guó)產(chǎn)開(kāi)源數(shù)據(jù)庫(kù)openGauss容器部署過(guò)程詳解
openGauss是一款開(kāi)源的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),它具有多核高性能、全鏈路安全性、智能運(yùn)維等企業(yè)級(jí)特性,這篇文章主要介紹了國(guó)產(chǎn)開(kāi)源數(shù)據(jù)庫(kù)openGauss容器部署,需要的朋友可以參考下2022-08-08
5分鐘快速了解數(shù)據(jù)庫(kù)死鎖產(chǎn)生的場(chǎng)景和解決方法
這篇文章主要給大家介紹了關(guān)于如何通過(guò)5分鐘快速理解數(shù)據(jù)庫(kù)死鎖的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
DBeaver操作數(shù)據(jù)表的拷貝的實(shí)現(xiàn)
這篇文章主要介紹了DBeaver操作數(shù)據(jù)表的拷貝的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

