暫時沒找到原因
表結構
/******************************************/ /* DatabaseName = bg_scm */ /* TableName = demeter_order_deliver */ /******************************************/ CREATE TABLE `demeter_order_deliver` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `order_no` varchar(64) NOT NULL COMMENT '訂單編號', `order_id` bigint(20) NOT NULL COMMENT '訂單ID', `order_deliver_no` varchar(64) NOT NULL COMMENT '發貨單編號', `stock_no` varchar(32) NOT NULL COMMENT '倉庫編碼', `stock_id` bigint(20) NOT NULL COMMENT '倉庫ID', `stock_name` varchar(10) NOT NULL COMMENT '倉庫名稱', `company_id` bigint(20) NOT NULL COMMENT '訂單所屬公司ID', `status` varchar(32) NOT NULL DEFAULT '0' COMMENT '發貨單狀態', `weight_total` decimal(8,2) DEFAULT NULL COMMENT '商品總重量', `volume_total` decimal(12,2) DEFAULT NULL COMMENT '商品總體積', `consignee_realname` varchar(32) NOT NULL COMMENT '收貨人姓名', `consignee_telphone` varchar(32) NOT NULL COMMENT '收貨人聯繫電話', `province_id` bigint(12) NOT NULL COMMENT '收貨省', `city_id` bigint(12) NOT NULL COMMENT '收貨市', `district_id` bigint(12) NOT NULL COMMENT '收貨區', `street_id` binary(12) DEFAULT NULL COMMENT '街道', `province_name` varchar(50) DEFAULT NULL COMMENT '省名稱', `city_name` varchar(50) DEFAULT NULL COMMENT '市名稱', `county_name` varchar(50) DEFAULT NULL COMMENT '區域名稱', `street_name` varchar(50) DEFAULT NULL COMMENT '街道', `address` varchar(250) NOT NULL COMMENT '收貨地址', `order_remark` varchar(256) DEFAULT NULL COMMENT '訂單備註', `statement_date` date DEFAULT NULL COMMENT '訂單歸屬日期', `estimate_deliver_date` datetime DEFAULT NULL COMMENT '預計送達時間', `real_deliver_date` datetime DEFAULT NULL COMMENT '實際送達時間', `out_stock_time` datetime DEFAULT NULL COMMENT '出庫時間', `store_id` bigint(20) NOT NULL COMMENT '店鋪id', `store_name` varchar(100) DEFAULT NULL COMMENT '店鋪名稱', `store_type` varchar(32) DEFAULT NULL COMMENT '店鋪類別', `business_type` varchar(32) DEFAULT NULL COMMENT '店鋪業務類型', `sort_proportion` int(11) DEFAULT '2' COMMENT '排序比重', `type` varchar(32) NOT NULL COMMENT '類型(配送、調度)', `route` varchar(20) DEFAULT NULL COMMENT '線路', `route_index` varchar(20) DEFAULT NULL COMMENT '線路序號', `route_platenumber` varchar(10) DEFAULT NULL COMMENT '車牌', `sorting_route` varchar(20) DEFAULT NULL COMMENT '分揀線路', `sorting` int(11) DEFAULT NULL COMMENT '分揀口', `number` int(11) NOT NULL DEFAULT '0' COMMENT '原始數量', `out_number` int(11) NOT NULL DEFAULT '0' COMMENT '出庫數量', `out_weight` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '出庫重量', `out_volume` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '出庫體積', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間', `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最後修改時間', `station_range_id` bigint(20) DEFAULT NULL COMMENT '配送站點範圍id', PRIMARY KEY (`id`), UNIQUE KEY `UK_ORDER_DELIVER_IDX` (`order_deliver_no`), KEY `NK_PLATE_NUMBER_IDX` (`estimate_deliver_date`,`route_platenumber`), KEY `NK_ORDER_NO_IDX` (`order_no`), KEY `NK_ORDER_ID_IDX` (`order_id`), KEY `NK_DATE_STORE_ID_IDX` (`store_id`,`estimate_deliver_date`) USING BTREE, KEY `idx_statement_date` (`statement_date`) USING BTREE, KEY `NK_ESTIMATE_COMAPNY_STOCK_IDX` (`estimate_deliver_date`,`company_id`,`stock_id`) ) ENGINE=InnoDB AUTO_INCREMENT=13816094 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='發貨單明細表' ;
數據量
SELECT count(1) FROM demeter_order_deliver
sql語句
explain SELECT * FROM demeter_order_deliver WHERE `estimate_deliver_date` >= ? AND `estimate_deliver_date` < ? and `company_id` = ? ORDER BY `id` DESC LIMIT 0, 10
某天突然sql告警 顯示這條sql執行60多秒 理論上是可以命中esttimate_deliver_date NK_ESTIMATE_COMAPNY_STOCK_IDX索引
我們手動執行以下也顯示正常
SELECT *FROM demeter_order_deliver WHERE `estimate_deliver_date` >= '2021-12-03 00:00:00.0' AND `estimate_deliver_date` < '2021-12-03 23:59:59.0' and `company_id` = 2 ORDER BY `id` DESC LIMIT 0, 10
數據行
但是發現以下sql就沒命中索引
SELECT * FROM demeter_order_deliver WHERE `estimate_deliver_date` >= '2021-12-03 00:00:00.0' AND `estimate_deliver_date` < '2021-12-03 23:59:59.0' and `company_id` = 3 ORDER BY `id` DESC LIMIT 0, 10
優化成了主鍵索引 導致全表掃描 條件爲3的數據行數只有1條
優化改爲強制使用索引
SELECT * FROM demeter_order_deliver FORCE INDEX(NK_ESTIMATE_COMAPNY_STOCK_IDX) WHERE `estimate_deliver_date` >= '2021-12-03 00:00:00.0' AND `estimate_deliver_date` < '2021-12-03 23:59:59.0' and `company_id` = 3 ORDER BY `id` DESC LIMIT 0, 10
總結
雖然不知道原因,但是不建議order by id 與limit一起使用