我們都知道where條件如果在字段上帶了函數就不會去走索引,不好優化,無意間了解到mysql一個新特性--虛拟列,專門處理這塊問題的,下面一起來了解下吧~
在MySQL 5.7中,支持兩種Generated Column,即Virtual Generated Column和Stored Generated Column,前者隻将Generated Column保存在數據字典中(表的元數據),并不會将這一列數據持久化到磁盤上;後者會将Generated Column持久化到磁盤上,而不是每次讀取的時候計算所得。很明顯,後者存放了可以通過已有數據計算而得的數據,需要更多的磁盤空間,與Virtual Column相比并沒有優勢,因此,MySQL 5.7中,不指定Generated Column的類型,默認是Virtual Column。
如果需要Stored Generated Golumn的話,可能在Virtual Generated Column上建立索引更加合适。綜上,一般情況下,都使用Virtual Generated Column,這也是MySQL默認的方式
<type> [ GENERATED ALWAYS ] AS ( <expression> ) [ VIRTUAL|STORED ] [ UNIQUE [KEY] ] [ [PRIMARY] KEY ] [ NOT NULL ] [ COMMENT <text> ]
假設有一個表,其中包含一個 date 類型的列 `SimpleDate` date
SimpleDate 是一個常用的查詢字段,并需要對其執行日期函數,例如
SELECT ... WHERE dayofweek(SimpleDate) = 3 ...
此時的問題是 即使對 SimpleDate 建立索引,這個查詢語句也無法使用,因為日期函數阻止了索引。
為了提高查詢效率,通常要進行額外的操作,例如新建一個字段 SimpleDate_dayofweek,存放 dayofweek(SimpleDate) 的計算結果,然後對這列創建索引,SimpleDate_dayofweek 的值需要程序寫入,例如使用觸發器,在 SimpleDate 有變動時更新 這樣查詢就可以改為
3、構建姓名的虛拟列
alter table user add user_name varchar(20) generated always as (data->'$.name');
4、構建索引
alter table user add index idx_name(user_name);
5、測試是否用到索引
explain select * from user where user_name='"hwb"' \G;
可以看出用了索引了
6、插入新數據
此時的表的結構由于多出了user_name這一虛拟列,再插入别的數據要注意在表後指明插入列(不能給虛拟列插入數據)
insert into user(uid,data) values (NULL,'{"name":"test","address":"shantou"}');
做完發現這個實驗好像不是那麼好理解...應該對比一下加不加虛拟列有沒走索引,可能會更容易讓大家理解的...後面會分享更多devops和DBA方面的内容,感興趣的朋友可以關注一下~
,
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!