美文网首页
MYSQL时间范围查询索引失效

MYSQL时间范围查询索引失效

作者: clicsug | 来源:发表于2019-11-15 17:04 被阅读0次

    近期在做一个报表监控的项目,主要的查询条件就是时间,每天导入数据库的数据大概几万条,页面的查询范围最多限制在1个月,算下来1个月的数据量最多有300w,功能开发完后自己做了100多万的测试数据,并在作为查询条件的时间字段上加了索引,但是测试时发现并不是每次用时间范围查询的时候都会走索引。
    表结构:
    CREATE TABLE vehicle_revision_redelivered (
    id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    thermosphere varchar(45) DEFAULT NULL COMMENT '温层',
    order_submit_time datetime DEFAULT NULL COMMENT '下单时间',
    collect_service varchar(45) DEFAULT NULL COMMENT '揽收服务',
    delivery_service varchar(45) DEFAULT NULL COMMENT '派送服务',
    expect_pickup_start_time datetime DEFAULT NULL COMMENT '预计揽件起始时间',
    expect_pickup_end_time datetime DEFAULT NULL COMMENT '预计揽件结束时间',
    expect_delivered_time datetime DEFAULT NULL COMMENT '应妥投时间时间',
    sys_redelivered_time datetime DEFAULT NULL COMMENT '系统操作再投时间',
    create_time datetime DEFAULT NULL COMMENT '创建时间',
    create_pin varchar(45) DEFAULT NULL COMMENT '创建人账号',
    PRIMARY KEY (id),
    KEY idx_expect_delivered_time (expect_delivered_time)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    测试数据量:1151136 条数据
    查询语句SQL1:
    explain
    SELECT create_time
    FROM vehicle_revision_redelivered
    where expect_delivered_time >= '2019-10-15 00:00:00' and expect_delivered_time<= '2019-10-30 23:59:59' ;
    打印结果 Result1:

    explain1.png

    查询语句SQL2:
    explain
    SELECT create_time
    FROM vehicle_revision_redelivered
    where expect_delivered_time >= '2019-11-21 00:00:00' and expect_delivered_time<= '2020-01-30 23:59:59' ;
    打印结果 Result2:

    result2.png

    同样的sql 不同的只是查询范围不同 第一走的全表扫描,第二个走的索引

    分析了一下,总数据量一共是1151136 条 ,10月15至10月30号数据量是290644条 占总数量的25.2% ,扫描行数1004564,11月21号至2020年1月30号数据量是106967,约占总数量的9.3% 扫描行数401360行, 数据主要集中在10月22至11月30号 ,这段时间的数据一共1091903条

    查询语句SQL3:
    explain
    SELECT create_time
    FROM vehicle_revision_redelivered
    where expect_delivered_time >= '2019-11-20 00:00:00' and expect_delivered_time<= '2020-01-30 23:59:59' ;
    查询结果Result3:

    result3.png
    11月20至1月30号的数据一共142514 占总数据量的12.3%,扫描行数1004564

    查询语句SQL4:
    explain
    SELECT create_time
    FROM vehicle_revision_redelivered
    where expect_delivered_time >= '2019-11-20 00:00:00' and expect_delivered_time<= '2020-01-23 23:59:59' ;
    查询结果Result4:

    Result4.png
    11月20号至1月23号的数据一共135789条 约占总数据量的 11.8%,扫描行数426220行

    当使用MySql 非主键索引进行查询时 如果扫描数据量接近全表数据量时,mysql会进行全表扫描不会使用索引(主键索引除外),这也是为什么不建议在区分度低的字段
    上建索引,也会导致全表扫描。
    rows不能直接理解为扫描行数, 表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数也就是mysql认为必须要逐行去检查和判断的记录的条数,实际是mysql根据估算的所需读取的行数决定是全表扫描还是使用索引

    相关文章

      网友评论

          本文标题:MYSQL时间范围查询索引失效

          本文链接:https://www.haomeiwen.com/subject/fgdsictx.html