mysql执行计划实战分析(1)--联合索引利用问题

目标

分析联合唯一索引问题查询sql的性能问题,执行计划结果含义学习可参考博客https://blog.csdn.net/da_guo_li/article/details/79008016
对于建立索引意见,参考博客
https://blog.csdn.net/wulex/article/details/69540136

背景

tbl_trx_order中有merchant_no、request_no两个字段作为联合索引,ddl为

CREATE TABLE
    tbl_trx_order
    (
        ID bigint NOT NULL AUTO_INCREMENT,
        CREATE_TIME DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
        LAST_UPDATE_TIME DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
        REQUEST_NO VARCHAR(128) NOT NULL,
        MERCHANT_NO VARCHAR(128) NOT NULL,
        ORDER_AMOUNT DECIMAL(10,2) NOT NULL,
        PAY_TOOL VARCHAR(32) NOT NULL,
        EXPIRE_TIME INT,
        ORDER_DATE DATETIME NOT NULL,
        TRX_EXTERNAL_NO VARCHAR(128) NOT NULL,
        PAY_EXTERNAL_NO VARCHAR(128),
        TRX_STATUS VARCHAR(32) NOT NULL,
        REFUND_AMOUNT DECIMAL(10,2) NOT NULL,
        PRODUCT_NAME VARCHAR(128),
        PRODUCT_DESC VARCHAR(128),
        ORDER_SOURCE VARCHAR(64),
        PAY_TYPE VARCHAR(64),
        PAY_SCENE VARCHAR(64),
        DISTRICT_INFO VARCHAR(64),
        DEVICE_NO VARCHAR(64),
        OPERATOR_NO VARCHAR(64),
        SERVER_CALLBACK_URL VARCHAR(128),
        REMARK VARCHAR(128),
        TRX_BATCH_NO VARCHAR(64),
        CANCEL_SIGN VARCHAR(32),
        SETTLE_SIGN VARCHAR(32),
        TERMINAL_NO VARCHAR(64),
        COMPLETED_TIME DATETIME,
        SUM_STATUS VARCHAR(32),
        PRIMARY KEY (ID),
        CONSTRAINT trxOrder_unique_index UNIQUE (REQUEST_NO, MERCHANT_NO),
        CONSTRAINT trxOrder_external_index UNIQUE (TRX_EXTERNAL_NO),
        INDEX TBL_TRX_ORDER_CREATE_TIME_INDEX (CREATE_TIME),
        INDEX TBL_TRX_ORDER_LAST_UPDATE_TIME_INDEX (LAST_UPDATE_TIME),
        INDEX TBL_TRX_ORDER_PAY_EXTERNAL_NO_INDEX (PAY_EXTERNAL_NO),
        INDEX TBL_TRX_ORDER_BATCH_NO_INDEX (TRX_BATCH_NO),
        INDEX TBL_TRX_ORDER_COMPLETED_TIME_INDEX (COMPLETED_TIME)
    )
    ENGINE=InnoDB DEFAULT CHARSET=utf8;

重点关注 CONSTRAINT trxOrder_unique_index UNIQUE (REQUEST_NO, MERCHANT_NO)

问题

  1. SELECT * FROM tbl_trx_order where request_no='lcPay1530699111557' and merchant_no='1318070417698'有没有利用索引
  1. SELECT * FROM tbl_trx_order where merchant_no='1318070417698' and request_no='lcPay1530699111557'有没有利用索引
  1. SELECT * FROM tbl_trx_order where merchant_no='1318070417698'有没有利用索引

  2. SELECT * FROM tbl_trx_order where request_no='lcPay1530699111557' 有没有利用索引

分析

  1. 问题1和2相似,主要是联合唯一索引使用的时候有没有顺序问题,看计划

explain SELECT * FROM tbl_trx_order where merchant_no='1318070417698' and request_no='lcPay1530699111557';

计划

explain SELECT * FROM tbl_trx_order where request_no='lcPay1530699111557' and merchant_no='1318070417698';

image.png

充分说明,联合索引的执行是和其两个参数的摆放先后顺序没有关系的.

  1. 问题3和4相似,问的主要是联合索引的多个参数单独使用时生不生效

explain SELECT * FROM tbl_trx_order where merchant_no='1318070417698';

image.png

explain SELECT * FROM tbl_trx_order where request_no='lcPay1530699111557';

image.png

可以看出,单独使用merchant_no时,索引并没有生效,且rows为575,相当于遍历了整表,type为ALL;而使用request_no 时,现在索引是生效的.
所以,联合索引中字段单独使用时,从联合索引前向后方向使用部分字段索引是生效的,这也叫做数据库的最佳左前缀特性.

下面举个多子端联合索引的例子测试一下:

CREATE TABLE
    tbl_check_batch
    (
        ID bigint NOT NULL AUTO_INCREMENT,
        CREATE_TIME DATETIME DEFAULT CURRENT_TIMESTAMP,
        LAST_UPDATE_TIME DATETIME DEFAULT CURRENT_TIMESTAMP,
        BATCH_NUM VARCHAR(64) NOT NULL,
        CHECK_STATUS VARCHAR(32) NOT NULL,
        CHECK_CONTROLER_ID bigint NOT NULL,
        BATCH_TYPE VARCHAR(32),
        PRIMARY KEY (ID),
        CONSTRAINT batch_num_record_unique_index UNIQUE (BATCH_NUM, CHECK_CONTROLER_ID, BATCH_TYPE)
    )
    ENGINE=InnoDB DEFAULT CHARSET=utf8;

例一: explain SELECT * FROM tbl_check_batch where BATCH_NUM='000000' and CHECK_CONTROLER_ID=1 ;

image.png

此时显然索引是生效的

例二: explain SELECT * FROM tbl_check_batch where CHECK_CONTROLER_ID=1 and BATCH_TYPE='TRADE';

image.png

显然此时索引是不生效的,索引证明我们上面的结论同样适用于2个以上联合索引的情况.

附:例子中涉及了BATCH_NUM是一个Varchar类型字段,如果此时sql如下
SELECT * FROM tbl_check_batch where BATCH_NUM=000000 and CHECK_CONTROLER_ID=1 and BATCH_TYPE='TRADE';我们是一样能查出结果的,但是切记mysql字段自动类型转换时索引时不生效的,我们生产使用时千万注意

image.png

你可能感兴趣的:(mysql执行计划实战分析(1)--联合索引利用问题)