记录一次Mysql慢Sql问题

暂时没找到原因

表结构

/******************************************/
/*   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 主键  与limit一起使用

原文地址:https://www.cnblogs.com/LQBlog/p/15658347.html