SQL優化之利用索引排序
近期在做資料庫的慢SQL優化,從資料庫慢日誌看到一個SQL執行時間大概1.7s,高峰時候達到十幾秒
mysql> SELECT id, service_seq, order_item_seq, status, order_time_type -> , reserve_time, user_name, user_contact, service_address_type, service_address_id -> , service_address, service_mode, insured_name, insured_identity, policy_no -> , create_time, update_time, over_time, artisan_id, product_id -> , user_id, longitude, latitude, refund_status, settle_status -> , comment_status, remark, insured_name, insured_identity, is_del -> , postpone_status, last_overdue_time, source_from, operator_id -> FROM order_service_item -> WHERE status = '10' -> AND reserve_time BETWEEN '2019-07-10 06:00:00.085' AND '2019-07-10 06:10:00.085' -> AND is_del = 0 -> ORDER BY id DESC; Empty set (1.77 sec)
執行計劃:
使用了index,但是掃描行數為489300,說明索引效率不高。
檢視錶結構:
show create table order_service_item; | order_service_item | CREATE TABLE `order_service_item` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID', `service_seq` varchar(40) COLLATE utf8_bin NOT NULL COMMENT '服務序列號', `order_item_seq` varchar(40) COLLATE utf8_bin NOT NULL COMMENT '訂單項序列號', `status` varchar(2) COLLATE utf8_bin DEFAULT NULL COMMENT '服務狀態: 00:新訂單 10:等待服務 20:取消處理 30:進行中 40:在路上 50:到達 60:美甲師處理完成 90:使用者處理完成', `reserve_time` datetime DEFAULT NULL COMMENT '預約時間', `user_name` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '客戶姓名', `user_contact` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '客戶聯絡電話', `service_address_id` varchar(40) COLLATE utf8_bin DEFAULT NULL, `service_address` varchar(400) COLLATE utf8_bin DEFAULT NULL COMMENT '服務地址', `service_mode` tinyint(2) DEFAULT '0' COMMENT '服務型別:0:普通 1:班課', `policy_no` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '保單號', `insured_name` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '被保險人姓名', `insured_identity` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '被保險人身份證', `create_time` datetime NOT NULL COMMENT '建立時間', `update_time` datetime NOT NULL COMMENT '更新時間', `artisan_id` varchar(40) COLLATE utf8_bin DEFAULT NULL COMMENT '手藝人ID', `product_id` varchar(40) COLLATE utf8_bin DEFAULT NULL COMMENT '作品ID', `user_id` varchar(40) COLLATE utf8_bin DEFAULT NULL COMMENT '客戶ID', `longitude` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '經度', `latitude` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '緯度', `refund_status` tinyint(2) DEFAULT '0' COMMENT '退款狀態:0 無退款 2 待處理 3 退款請求失敗 4 退款請求成功 5 退款失敗 6 處理完成 8 退款成功', `settle_status` tinyint(2) DEFAULT '0' COMMENT '結算狀態', `comment_status` tinyint(2) DEFAULT '0' COMMENT '評論狀態 0 未評論 1 已評論', `remark` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '備註', `last_update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `order_time_type` tinyint(4) DEFAULT NULL COMMENT '服務時間型別\n:0 隨叫隨到\n 1 預約美甲 2 買約分離', `service_address_type` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '服務地址型別:home(顧客家), store(獨立手藝人自定義的門店), store_self(門店手藝人所屬門店), studio(原小聚點)', `over_time` datetime DEFAULT NULL COMMENT '服務完成時間', `is_del` tinyint(1) DEFAULT '0' COMMENT '刪除標記 0 未刪除 1 已刪除', `postpone_status` tinyint(2) DEFAULT '0' COMMENT '延期標識:0 未過期 1 已過期 2 延期申請中 3 已延期 4 超期取消 5 拒絕延期', `last_overdue_time` datetime DEFAULT NULL COMMENT '最後過期時間', `source_from` int(3) DEFAULT NULL COMMENT '20代表套餐預約來的', `operator_id` varchar(40) COLLATE utf8_bin DEFAULT NULL COMMENT '具體執行服務的手藝人的ID', `verificat_code` varchar(20) COLLATE utf8_bin DEFAULT '' COMMENT '天貓核銷碼', PRIMARY KEY (`id`), UNIQUE KEY `index_service_seq` (`service_seq`), KEY `index_order_item_seq` (`order_item_seq`), KEY `index_user_id` (`user_id`), KEY `index_artisan_id` (`artisan_id`), KEY `index_status` (`status`), KEY `index_product_id` (`product_id`), KEY `idx_last_update_time` (`last_update_time`), KEY `idx_comment_status` (`comment_status`,`status`) ) ENGINE=InnoDB AUTO_INCREMENT=11593152 DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC COMMENT='訂單服務項表' |
針對這個SQL,在status,reserve_time,is_del和id欄位建立聯合索引,
alter table order_service_item add index idx_sta_rt_del_id (status,reserve_time,is_del,id);
檢視執行計劃:
執行計劃走了新建的聯合索引,並且檢索行數變成了1行。
檢視執行時間:
mysql> SELECT id, service_seq, order_item_seq, status, order_time_type -> , reserve_time, user_name, user_contact, service_address_type, service_address_id -> , service_address, service_mode, insured_name, insured_identity, policy_no -> , create_time, update_time, over_time, artisan_id, product_id -> , user_id, longitude, latitude, refund_status, settle_status -> , comment_status, remark, insured_name, insured_identity, is_del -> , postpone_status, last_overdue_time, source_from, operator_id -> FROM order_service_item -> WHERE status = '10' -> AND reserve_time BETWEEN '2019-07-10 06:00:00.085' AND '2019-07-10 06:10:00.085' -> AND is_del = 0 -> ORDER BY id DESC; Empty set (0.00 sec)
執行時間已經降到了ms級別。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30135314/viewspace-2650105/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL優化案例-分割槽索引之無字首索引(六)SQL優化索引
- SQL優化之統計資訊和索引SQL優化索引
- 《MySQL慢查詢優化》之SQL語句及索引優化MySql優化索引
- MySQL調優之索引優化MySql索引優化
- MySQL優化之索引解析MySql優化索引
- Mysql索引優化之索引的分類MySql索引優化
- sql優化之邏輯優化SQL優化
- 資料庫效能優化-索引與sql相關優化資料庫優化索引SQL
- Oracle SQL優化之sql tuning advisorOracleSQL優化
- SQL優化案例-自定義函式索引(五)SQL優化函式索引
- SQL優化案例-正確的使用索引(二)SQL優化索引
- SQL精華總結索引型別優化SQL優化事務大表優化思維導圖❤️SQL索引型別優化
- mysql優化 | 儲存引擎,建表,索引,sql的優化建議MySql優化儲存引擎索引
- SQL優化之limit 1SQL優化MIT
- MySQL之SQL優化技巧MySql優化
- SQL效能最佳化之索引最佳化法SQL索引
- MySQL效能優化之索引設計MySql優化索引
- SQL最佳化案例-分割槽索引之無字首索引(六)SQL索引
- 理解索引:索引優化索引優化
- Oracle優化案例-分割槽索引之無字首索引(六)Oracle優化索引
- MySQL之SQL語句優化MySql優化
- MySQL優化學習筆記之索引MySql優化筆記索引
- 【MySQL】三、效能優化之 覆蓋索引MySql優化索引
- MySQL優化之覆蓋索引的使用MySql優化索引
- oracle全文索引之同步和優化索引做了什麼Oracle索引優化
- 十七、Mysql之SQL優化查詢MySql優化
- MySQL之SQL優化詳解(二)MySql優化
- MySQL之SQL優化詳解(三)MySql優化
- MySQL之SQL優化詳解(一)MySql優化
- Elasitcsearch索引優化索引優化
- MySQL索引優化MySql索引優化
- mysql優化索引MySql優化索引
- MySQL 優化之 index_merge (索引合併)MySql優化Index索引
- msyql千萬級別查詢優化之索引優化索引
- 神奇的 SQL 之效能優化 → 讓 SQL 飛起來SQL優化
- Orderby 排序優化排序優化
- MySQL 索引和 SQL 調優總結MySql索引
- OGG複製程式延遲高,優化方法二(存在索引),SQL選擇不好的索引優化索引SQL