MySQL 生成列索引
MySQL支援在生成列上建立索引,例如:
mysql> create table t1(f1 int,gc int as (f1+1) stored,index(gc)); Query OK, 0 rows affected (0.11 sec) mysql> insert into t1(f1) values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10); Query OK, 10 rows affected (0.03 sec) Records: 10 Duplicates: 0 Warnings: 0 mysql> select * from t1; +------+------+ | f1 | gc | +------+------+ | 1 | 2 | | 2 | 3 | | 3 | 4 | | 4 | 5 | | 5 | 6 | | 6 | 7 | | 7 | 8 | | 8 | 9 | | 9 | 10 | | 10 | 11 | +------+------+ 10 rows in set (0.00 sec)
生成列gc,它的定義為表示式f1+1。這個列gc也建立了索引因此在生成執行計劃時最佳化器可以使用這個索引。下面的查詢where條件引用了列gc並且最佳化器會考慮使用這個索引是否可以生成更有效的執行計劃:
mysql> explain select * from t1 where gc>9\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t1 partitions: NULL type: range possible_keys: gc key: gc key_len: 5 ref: NULL rows: 2 filtered: 100.00 Extra: Using index condition
最佳化器可以在生成的列上使用索引來生成執行計劃,即使在查詢中沒有按名稱直接引用這些列的情況下也是如此。如果where,order by 或group by子句引用的表示式與某些被索引的生成列相匹配就會出現這種情況。下面的查詢沒有直接引用生成列gc,但使用的表示式與生成列gc的定義匹配:
mysql> explain select * from t1 where f1+1>9\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t1 partitions: NULL type: range possible_keys: gc key: gc key_len: 5 ref: NULL rows: 2 filtered: 100.00 Extra: Using index condition
最佳化器識別出了表示式f1+1與生成列gc相匹配並且gc列建立了索引,所以最佳化器在生成執行計劃時考慮使用了該索引。
實際上,最佳化器已經用與表示式匹配的生成列的名稱gc替換了表示式f1 + 1。這在執行show warnings命令所顯示的擴充套件解釋資訊中可以很明顯地看到重寫查詢語句確實用生成列替換了表示式。
mysql> show warnings\G; *************************** 1. row *************************** Level: Note Code: 1003 Message: /* select#1 */ select `mysql`.`t1`.`f1` AS `f1`,`mysql`.`t1`.`gc` AS `gc` from `mysql`.`t1` where (`mysql`.`t1`.`gc` > 9) 1 row in set (0.00 sec)
最佳化器使用生成列索引有以下限制和條件:
.對於一個查詢語句的表示式是否成生成列定義相匹配,那麼表示式必須完全相同並且有相同的結果型別。例如,如果生成列表示式是f1+1,如果查詢使用1+f1或者如查f1+1(一個整數表示式)與字元進行比較而不是數字那麼最佳化器將不會認為是匹配的。
.對於這些操作:=,< ,<=,>,>=,between和in最佳化器處理是,對於不是between和in之外的其它運算子而言,任何一個運算元都可以被匹配的生成列所替換。對於between和in運算子,只有第一個引數可以被匹配的生成列替換,並且其它的引數必須要有相同的結果型別。between和in運算子目前還不支援對JSON的呼叫。
.生成列必須定義為至少包含一個函式呼叫或前一項中提到的一個運算子的表示式。表示式不能只是簡單的引用其它列。例如,gc int as (f1) stored,這個生成列的定義只是簡單的引用了一個列,因此在生成列gc上的索引不會被最佳化器考慮。
.為了比較字串與呼叫JSON函式返回帶引號的字串的被索引的生成列,JSON_UNQUOTE()函式需要在生成列定義中用來刪除函式返回值的引號(對於直接比較字串與函式值,JSON比較器控制程式碼會刪了引號,但在索引查詢時不會發生)。
.如果最佳化器未能選擇所需的索引,則可以使用索引提示強制最佳化器做出不同的選擇。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26015009/viewspace-2750300/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL通過通用列索引來提供一個JSON列索引MySql索引JSON
- MySQL單列索引和組合索引的區別MySql索引
- MySQL單列索引和組合索引的區別介紹MySql索引
- Mysql多列索引建立與優化.mdMySql索引優化
- MySQL5.7 虛擬列實現表示式索引MySql索引
- mysql索引之字首索引MySql索引
- ElasticSearch 索引 VS MySQL 索引Elasticsearch索引MySql
- MySQL — 索引MySql索引
- MySQL 索引MySql索引
- mysql索引MySql索引
- [Mysql]索引MySql索引
- mysql 索引( mysql index )MySql索引Index
- 認識SQLServer索引以及單列索引和多列索引的不同SQLServer索引
- 索引與null(一):單列索引索引Null
- 什麼是行儲存和列儲存?正排索引和倒排索引?MySQL既不是倒排索引,也索引MySql
- MySQL索引系列:全文索引MySql索引
- MySQL 字串索引和字首索引MySql字串索引
- MySQL 索引 +explainMySql索引AI
- MySQL索引原理MySql索引
- MySQL InnoDB 索引MySql索引
- MySQL 索引初探MySql索引
- MySQL 二 索引MySql索引
- Mysql索引使用MySql索引
- MySQL之索引MySql索引
- mysql新增索引MySql索引
- MySQL的索引MySql索引
- mysql組合索引,abc索引命中MySql索引
- Mysql索引結構與索引原理MySql索引
- MySQL索引之空間索引(SPATIAL)MySql索引
- FAQ系列|MySQL索引之聚集索引MySql索引
- MySQL 唯一索引和普通索引MySql索引
- 【原創】MySQL5.7 虛擬列實現表示式索引薦MySql索引
- 【MySQL(2)| MySQL索引機制】MySql索引
- MySql(一) 淺析MySql索引MySql索引
- MySQL 聚簇索引 和覆蓋索引MySql索引
- MySQL索引(二):建索引的原則MySql索引
- MYSQL索引及高效能索引策略MySql索引
- MySQL 字首索引——讓索引減負狂奔MySql索引