把兩個單獨的索引合並成一個組合索引,即把where條件字段的索引和group by的分組字段索引組合成一個。
如果分組的字段需要用函數處理,可以用索引函數
Generated Column(函數索引)
mysql5.7版本,函數索引用虛擬列,virtual是查詢時在內存中計算,而store是計算好后存放在磁盤中。一般作為索引,默認用virtual。
語法:
<type> [ GENERATED ALWAYS ] AS ( <expression> ) [ VIRTUAL|STORED ] [ UNIQUE [KEY] ] [ [PRIMARY] KEY ] [ NOT NULL ] [ COMMENT <text> ]
修改table添加一個新列,由函數處理已有字段自動生成。
新建虛擬列
ALTER TABLE tblName ADD virtualField varchar(50) GENERATED ALWAYS AS (FROM_UNIXTIME(bus_remind.arrivingTimeStamp)) virtual;
刪除虛擬列
alter table tblName drop column fieldName;
例子
組合索引如下
sql語句
SELECT avg(arrivingBattery) AS battery FROM bus_remind WHERE parkingCode = '101001' GROUP BY DATE_FORMAT( FROM_UNIXTIME(arrivingTimeStamp ), '%Y-%m-%d %H:%i' )
explain結果
分析原因:
分組字段根據分鍾分組(對字段進行函數處理)導致拋棄索引。
解決方案:
復合索引使用虛擬列技術,將虛擬列作為索引,Sql如下
/*創建*/ ALTER TABLE bus_remind ADD virtualArrivingTimeStamp char(16) GENERATED ALWAYS AS (DATE_FORMAT(FROM_UNIXTIME(arrivingTimeStamp),'%Y-%m-%d %H:%i')) VIRTUAL comment '來車時間函數索引列'; /*刪除*/ alter table bus_remind drop column virtualArrivingTimeStamp
復合索引更改為(版本必須為5.7及以上)
sql語句更改
SELECT avg(arrivingBattery) AS battery FROM bus_remind WHERE parkingCode = '101001' GROUP BY virtualArrivingTimeStamp
explain結果