【原創】MySQL 模擬條件索引
我們知道,MySQL 不支援條件索引。 什麼是條件索引呢? 條件索引就是在索引列上根據WHERE條件進行一定的過濾後產生的索引。 這樣的索引有以下優勢:
第一點, 比基於這個列的全部索引佔用空間來的小。
第二點, 特別是基於FULL INDEX SCAN 的時候,佔用空間小的索引對記憶體佔用也小很多。
PostgreSQL,SqlServer等都支援條件索引,所以我們先來看下條件索引的實際情況。
表結構如下,記錄大概有10W行:
Table "ytt.girl1"
Column | Type | Modifiers
--------+---------+--------------------
id | integer | not null
rank | integer | not null default 0
Indexes:
"girl1_pkey" PRIMARY KEY, btree (id)
"idx_girl1_rank" btree (rank) WHERE rank >= 10 AND rank <= 100
執行的查詢語句為:
select * from girl1 where rank between 20 and 60 limit 20;
用了全部索引的查詢計劃:
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.29..36.58 rows=20 width=8) (actual time=0.024..0.054 rows=20 loops=1)
-> Index Scan using idx_girl1_rank on girl1 (cost=0.29..421.26 rows=232 width=8) (actual time=0.023..0.044 rows=20 loops=1)
Index Cond: ((rank >= 20) AND (rank <= 60))
Total runtime: 0.087 ms
(4 rows)
Time: 1.881 ms
用了條件索引的查詢計劃:
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.28..35.54 rows=20 width=8) (actual time=0.036..0.068 rows=20 loops=1)
-> Index Scan using idx_girl1_rank on girl1 (cost=0.28..513.44 rows=291 width=8) (actual time=0.033..0.061 rows=20 loops=1)
Index Cond: ((rank >= 20) AND (rank <= 60))
Total runtime: 0.106 ms
(4 rows)
Time: 0.846 ms
可以看出,在掃描的記錄數以及時間上,條件索引的優勢都很明顯。
接下來,我們在MySQL 模擬下這樣的過程。
由於MySQL 不支援這樣的索引, 在SQL層面上,只能建立一個索引表來儲存對應條件的主鍵以及索引鍵。
ytt>show create table girl1_filtered_index;
+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| girl1_filtered_index | CREATE TABLE `girl1_filtered_index` (
`id` int(11) NOT NULL,
`rank` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_rank` (`rank`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
接下來,對基礎表的更新操作做下修改,建立了三個觸發器。
DELIMITER $$
USE `t_girl`$$
DROP TRIGGER `filtered_insert`$$
CREATE
TRIGGER `filtered_insert` AFTER INSERT ON `girl1`
FOR EACH ROW BEGIN
IF new.rank BETWEEN 10 AND 100 THEN
INSERT INTO girl1_filtered_index VALUES (new.id,new.rank);
END IF;
END;
$$
DELIMITER ;
DELIMITER $$
USE `t_girl`$$
DROP TRIGGER `filtered_update`$$
CREATE
TRIGGER `filtered_update` AFTER UPDATE ON `girl1`
FOR EACH ROW BEGIN
IF new.rank BETWEEN 10 AND 100 THEN
REPLACE girl1_filtered_index VALUES (new.id,new.rank);
ELSE
DELETE FROM girl1_filtered_index WHERE id = old.id;
END IF;
END;
$$
DELIMITER ;
DELIMITER $$
USE `t_girl`$$
DROP TRIGGER `filtered_delete`$$
CREATE
TRIGGER `filtered_delete` AFTER DELETE ON `girl1`
FOR EACH ROW BEGIN
DELETE FROM girl1_filtered_index WHERE id = old.id;
END;
$$
DELIMITER ;
OK,我們匯入測試資料。
ytt>load data infile 'girl1.txt' into table girl1 fields terminated by ',';
Query OK, 100000 rows affected (1.05 sec)
Records: 100000 Deleted: 0 Skipped: 0 Warnings: 0
ytt>select count(*) from girl1;
+----------+
| count(*) |
+----------+
| 100000 |
+----------+
1 row in set (0.04 sec)
ytt>select count(*) from girl1_filtered_index;
+----------+
| count(*) |
+----------+
| 640 |
+----------+
1 row in set (0.00 sec)
這裡,我們把查詢語句修改成基礎表和條件索引表的JOIN。
select a.id,a.rank from girl1 as a where a.id in (select b.id from girl1_filtered_index as b where b.rank between 20 and 60) limit 20;
當然這只是功能上的一個演示。 最終實現得靠MySQL 5.8了。^____^
©著作權歸作者所有:來自51CTO部落格作者david_yeung的原創作品,如需轉載,請註明出處,否則將追究法律責任
MySQL最佳化條件索引MySQL效能最佳化
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2157/viewspace-2820670/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql條件查詢MySql
- MySQL索引建立原則MySql索引
- MySQL索引(二):建索引的原則MySql索引
- mysql 索引設計原則MySql索引
- Oracle 條件索引 case when 報錯解決方案Oracle索引
- MySQL 索引的設計原則MySql索引
- mysql拆分字串做條件查詢MySql字串
- MySQL筆記 10 條件邏輯MySql筆記
- mysql 插入時帶判斷條件MySql
- 模擬退火演算法Python程式設計(2)約束條件的處理演算法Python程式設計
- Mysql研磨之設計索引原則MySql索引
- 「 MySQL高階篇 」MySQL索引原理,設計原則MySql索引
- update表中index索引列對原索引條目做什麼操作?Index索引
- MySQL 針對 like 條件的優化MySql優化
- MySQL函式-條件判斷函式MySql函式
- 資料庫聚簇索引——not null條件對唯一鍵索引成為聚簇索引的影響資料庫索引Null
- MySQL如何建立一個好索引?建立索引的5條建議【宇哥帶你玩轉MySQL 索引篇(三)】MySql索引
- 六條幹貨幫你的MySQL索引起飛MySql索引
- jsp+servlet+mysql多條件模糊查詢JSServletMySql
- 小程式代理創業成功的五個條件創業
- MySQL索引下推,原來這麼簡單!MySql索引
- MySQL組合索引和最左匹配原則MySql索引
- 帶約束條件的運籌規劃問題求解(模擬退火演算法實現)演算法
- 【原創】MySQL 返回更新值(RETURNING)MySql
- CSS 如何模擬“真實的”進度條?CSS
- MySQL條件判斷IF,CASE,IFNULL語句詳解MySqlNull
- 《MySQL 入門教程》第 08 篇 過濾條件MySql
- MySQL全面瓦解7:查詢的過濾條件MySql
- mysql帶AND關鍵字的多條件查詢MySql
- mysql,where條件查詢等學習筆記MySql筆記
- Python數模筆記-NetworkX(3)條件最短路徑Python筆記
- 【Stmplib】Python正確模擬傳送QQ郵件Python
- 模擬郵件伺服器,批量註冊利器伺服器
- MySQL-08.索引的建立和設計原則MySql索引
- MySQL學習筆記:組合索引-最左原則MySql筆記索引
- Mysql中聯合索引的最左匹配原則MySql索引
- 條件渲染
- mysql索引之字首索引MySql索引