• 线上MySQL慢查询现象案例--Impossible WHERE noticed after reading const tables


    前言:2012年的笔记整理而得,发布个人博客,做备忘录使用。
    背景:线上慢查询日志监控,得到如下的语句:
          发现:select doc_text from t_wiki_doc_text where doc_title = '谢泽源'; 这条语句昨天执行特别的慢

    1.查看上述语句的执行计划:
     mysql> explain select doc_text from t_wiki_doc_text where doc_title = '谢泽源';
    +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
    +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
    | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
    +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
    1 row in set (0.01 sec)
    发现了Impossible where noticed after reading const tables,这是一个有趣的现象?(经查找,这个会全表扫描)

    解释原因如下:
    根据主键查询或者唯一性索引查询,如果这条数据没有的话,它会全表扫描,然后得出一个结论,该数据不在表中。
    对于高并发的库来说,这条数据,会让负载特别的高。

    查看线上的表结构,也印证的上述说法:

    | t_wiki_doc_text | CREATE TABLE `t_wiki_doc_text` (
    `DOC_ID` bigint(12) NOT NULL COMMENT '词条ID流水号',
    `DOC_TITLE` varchar(255) NOT NULL COMMENT '条目原始标题',
    `DOC_TEXT` mediumtext COMMENT '条目正文',
    PRIMARY KEY (`DOC_ID`),
    UNIQUE KEY `IDX_DOC_TITLE` (`DOC_TITLE`)(唯一索引)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

    对此,我在自己的数据库里面,做了一个测试。

    ----------------------------------------------------测试模拟-----------------------------------------------------------
    1).建立一个有唯一索引的表。
    CREATE TABLE `zsd01` (
    `id` int(11) DEFAULT NULL,
    `name` varchar(20) DEFAULT NULL,
    UNIQUE KEY `idx_name` (`name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=gbk


    2).插入两条数据
    insert into zsd01 values(1,'a');
    insert into zsd01 values(2,'b');

    3).分析一个没有数据记录的执行计划。(例如select name from zsd01 where name ='c'; )
    mysql> explain select name from zsd01 where name ='c';
    +----+-------------+-------+------+---------------+------+---------+------+-----
    -+-----------------------------------------------------+
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows
    | Extra |
    +----+-------------+-------+------+---------------+------+---------+------+-----
    -+-----------------------------------------------------+
    | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL
    Impossible WHERE noticed after reading const tables |
    +----+-------------+-------+------+---------------+------+---------+------+-----
    -+-----------------------------------------------------+

    发现跟上述情况一模一样。

    4.) 修改表结构为只有一般索引的情况。
    CREATE TABLE `zsd01` (
    `id` int(11) DEFAULT NULL,
    `name` varchar(20) DEFAULT NULL,
    KEY `idx_normal_name` (`name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=gbk

    5.) 查看执行计划。
    mysql> explain select name from zsd01 where name ='c';
    +----+-------------+-------+------+-----------------+-----------------+---------
    +-------+------+--------------------------+
    | id | select_type | table | type | possible_keys | key | key_len
    | ref | rows | Extra |
    +----+-------------+-------+------+-----------------+-----------------+---------
    +-------+------+--------------------------+
    | 1 | SIMPLE | zsd01 | ref | idx_normal_name | idx_normal_name | 43
    | const | 1 | Using where; Using index |
    +----+-------------+-------+------+-----------------+-----------------+---------
    +-------+------+--------------------------+
    1 row in set (0.00 sec)
    发现,就正常走了一般索引,rows=1的执行开销。

    结论:从上述的例子和现象可以看出,如果数据不用唯一的话,普通的索引比唯一索引更好用。
  • 相关阅读:
    javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
    Maven无法下载com.oracle:ojdbc14:jar解决方法
    打赏
    badge徽章、挂件模版
    adb修改手机分辨率
    git忽略上传文件git忽略上传文件
    python爬虫用drony转发进行抓包转发
    pycharm远程服务器进行调试
    Ubuntu上latex+atom配置
    Ubuntu下设置开机后自动运行命令
  • 原文地址:https://www.cnblogs.com/jpfss/p/9154304.html
Copyright © 2020-2023  润新知