1. 程式人生 > >mysql5.7虛擬列初次嘗試

mysql5.7虛擬列初次嘗試

always extra com default efault rate 分享 png comment

添加虛擬列
ALTER TABLE erp_new_source_reports add client_name VARCHAR(80)  generated always as (clients->"$.name"); 
ALTER TABLE erp_new_source_reports add client_type VARCHAR(20)  generated always as (clients->"$.type"); 
ALTER TABLE erp_new_source_reports add client_relation VARCHAR(80)  generated always as (clients->"$.relation"); 
ALTER TABLE erp_new_source_reports add status_report_check  VARCHAR(80)  generated always as (status->"$.report_check"); 
 解釋: 
      erp_new_source_reports 表
      status_report_check  虛擬列名字
              status->"$.report_check(status是json字段,report_check是字段裏面的數據

技術分享圖片

MySQL 5.7.7 labs版本開始InnoDB存儲引擎已經原生支持JSON格式,該格式不是簡單的BLOB類似的替換。原生的JSON格式支持有以下的優勢![]

JSON數據有效性檢查:BLOB類型無法在數據庫層做這樣的約束性檢查
查詢性能的提升:查詢不需要遍歷所有字符串才能找到數據
支持索引:通過虛擬列的功能可以對JSON中的部分數據進行索引

例如創建數據庫:

    CREATE TABLE `erp_new_source_reports` (

id int(10) unsigned NOT NULL AUTO_INCREMENT,
agent_id int(11) DEFAULT NULL COMMENT ,

from varchar(191) COLLATE utf8_unicode_ci NOT NULL DEFAULT ‘self‘ COMMENT ,
company_id int(11) NOT NULL COMMENT ,
company_name varchar(191) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT ,
client_id int(11) DEFAULT NULL COMMENT ,
community_id int(11) NOT NULL COMMENT ,
status json NOT NULL COMMENT ‘狀態‘,
is_invalid
tinyint(4) NOT NULL DEFAULT ‘0‘,
created_at timestamp NULL DEFAULT NULL,
company_id int(11) NOT NULL COMMENT ‘公司ID‘,
deleted_at timestamp NULL DEFAULT NULL,
clients json DEFAULT NULL,
client_mobile varchar(128) COLLATE utf8_unicode_ci GENERATED ALWAYS AS (json_extract(clients,‘$.mobile‘)) VIRTUAL,
status_report_check varchar(80) COLLATE utf8_unicode_ci GENERATED ALWAYS AS (json_extract(status,‘$.report_check‘)) VIRTUAL,
PRIMARY KEY (id),
KEY idx_reports_sup (deleted_at,is_invalid,from,client_mobile,company_id,created_at) USING BTREE,
KEY reports_community_id_index1 (is_invalid,from,status_report_check,community_id,company_id,created_at) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=19126 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

查詢語句:

SELECT COUNT(`id`) AS aggregate
FROM `erp_new_source_reports`
WHERE (`from` = ‘self‘)
    AND (`created_at` >= ‘2019-04-07 00:00:00‘
        AND `created_at` <= ‘2019-04-08 23:59:59‘)
    AND (`status` -> ‘$."report_check"‘ = ‘verify‘)
    AND (`is_invalid` = 0)
    AND `erp_new_source_reports`.`deleted_at` IS NULL
    AND `erp_new_source_reports`.`company_id` = 1

初期是直接使用json直接查詢的 查詢速度:1.8s

技術分享圖片

執行計劃:

技術分享圖片

索引數據:

技術分享圖片

重點:

添加虛擬列 並添加進索引
    ALTER TABLE erp_new_source_reports add status_report_check  VARCHAR(80)  generated always as (status->"$.report_check"); 
##### 添加進索引

技術分享圖片

修改sql為
SELECT COUNT(`id`) AS aggregate
FROM `erp_new_source_reports`
WHERE (`from` = ‘self‘)
    AND (`created_at` >= ‘2019-04-07 00:00:00‘
        AND `created_at` <= ‘2019-04-08 23:59:59‘)
    AND status_report_check =‘verify‘
    AND (`is_invalid` = 0)
    AND `erp_new_source_reports`.`deleted_at` IS NULL
    AND `erp_new_source_reports`.`company_id` = 1;    
再次執行 執行計劃

技術分享圖片

查詢速度技術分享圖片

mysql5.7虛擬列初次嘗試