如何查看sql查询是否用到索引(mysql)

问题发现

我认为一条很简单的SQL然后跑了很久,明明我已经都建立相应的索引,逻辑也不需要优化。

SELECT a.custid, b.score, b.xcreditscore, b.lrscore
FROM (
    SELECT DISTINCT custid
    FROM sync.`credit_apply`
    WHERE SUBSTR(createtime, 1, 10) >= '2019-12-15'
        AND rejectrule = 'xxxx'
) a
    LEFT JOIN (
        SELECT *
        FROM sync.`credit_creditchannel`
    ) b
    ON a.custid = b.custid;

查看索引状态:

credit_apply表

mysql> show index from sync.`credit_apply`;
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table        | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| credit_apply |          0 | PRIMARY  |            1 | applyId     | A         |     1468496 | NULL     | NULL   |      | BTREE      |         |               |
| credit_apply |          1 | index2   |            1 | custId      | A         |      666338 | NULL     | NULL   |      | BTREE      |         |               |
| credit_apply |          1 | index2   |            2 | createTime  | A         |     1518231 | NULL     | NULL   |      | BTREE      |         |               |
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

或者

CREATE TABLE `credit_apply` (
  `applyId` bigint(20) NOT NULL AUTO_INCREMENT,
  `custId` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
  `ruleVersion` int(11) NOT NULL DEFAULT '1',
  `rejectRule` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT 'DP0000',
  `status` tinyint(4) NOT NULL DEFAULT '0',
  `extra` text COLLATE utf8mb4_unicode_ci,
  `createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `mobile` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT '',
  PRIMARY KEY (`applyId`) USING BTREE,
  KEY `index2` (`custId`,`createTime`)
) ENGINE=InnoDB AUTO_INCREMENT=1567035 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci



sync.`credit_creditchannel`表

mysql> show index from sync.`credit_creditchannel` ;
+----------------------+------------+-----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table                | Non_unique | Key_name                    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------------------+------------+-----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| credit_creditchannel |          0 | PRIMARY                     |            1 | recId       | A         |      450671 | NULL     | NULL   |      | BTREE      |         |               |
| credit_creditchannel |          1 | nationalId_custid           |            1 | nationalId  | A         |      450770 | NULL     | NULL   |      | BTREE      |         |               |
| credit_creditchannel |          1 | nationalId_custid           |            2 | custId      | A         |      450770 | NULL     | NULL   | YES  | BTREE      |         |               |
| credit_creditchannel |          1 | credit_creditchannel_custId |            1 | custId      | A         |      450770 |       10 | NULL   | YES  | BTREE      |         |               |
+----------------------+------------+-----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

 或者

CREATE TABLE `credit_creditchannel` (
  `recId` bigint(20) NOT NULL AUTO_INCREMENT,
  `nationalId` varchar(128) NOT NULL DEFAULT '',
  `identityType` varchar(3) NOT NULL DEFAULT '',
  `brief` mediumtext,
  `score` decimal(10,4) NOT NULL DEFAULT '0.0000',
  `npaCode` varchar(128) NOT NULL DEFAULT '',
  `basic` mediumtext,
  `createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `request` mediumtext,
  `custId` varchar(128) DEFAULT '',
  `xcreditScore` decimal(10,4) DEFAULT '0.0000',
  `queryTime` varchar(24) DEFAULT '',
  `lrScore` decimal(10,4) DEFAULT '0.0000',
  PRIMARY KEY (`recId`) USING BTREE,
  KEY `nationalId_custid` (`nationalId`,`custId`),
  KEY `credit_creditchannel_custId` (`custId`(10))
) ENGINE=InnoDB AUTO_INCREMENT=586557 DEFAULT CHARSET=utf8 

我们都可以看到相应的索引。以现在简单的sql逻辑理论上走custid这个索引就好了

解释函数explain

mysql> explain SELECT a.custid, b.score, b.xcreditscore, b.lrscore FROM(
SELECT DISTINCT custid FROM sync.`credit_apply` WHERE SUBSTR(createtime, 1, 10) >= '2019-12-15' AND rejectrule = 'xxx') a
LEFT JOIN 
(select * from sync.`credit_creditchannel`) b
ON a.custid = b.custid;
+----+-------------+----------------------+------------+-------+---------------+--------+---------+------+---------+----------+----------------------------------------------------+
| id | select_type | table                | partitions | type  | possible_keys | key    | key_len | ref  | rows    | filtered | Extra                                              |
+----+-------------+----------------------+------------+-------+---------------+--------+---------+------+---------+----------+----------------------------------------------------+
|  1 | PRIMARY     | <derived2>           | NULL       | ALL   | NULL          | NULL   | NULL    | NULL |  158107 |   100.00 | NULL                                               |
|  1 | PRIMARY     | credit_creditchannel | NULL       | ALL   | NULL          | NULL   | NULL    | NULL |  450770 |   100.00 | Using where; Using join buffer (Block Nested Loop) |
|  2 | DERIVED     | credit_apply         | NULL       | index | index2        | index2 | 518     | NULL | 1581075 |    10.00 | Using where                                        |
+----+-------------+----------------------+------------+-------+---------------+--------+---------+------+---------+----------+----------------------------------------------------+
3 rows in set (0.06 sec)

如何去看我们的SQL是否走索引?

我们只需要注意一个最重要的type 的信息很明显的提现是否用到索引:

type结果

type结果值从好到坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

一般来说,得保证查询至少达到range级别,最好能达到ref,否则就可能会出现性能问题。

possible_keys:sql所用到的索引

key:显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL

rows: 显示MySQL认为它执行查询时必须检查的行数。

分析:

我们的credit_creditchannel是ALL,而possible_keys是NULL索引在查询该表的时候并没有用到索引怪不得这么慢!!!!!!!!!

猜你喜欢

转载自www.cnblogs.com/wqbin/p/12124621.html