• MySQL通过Explain查看select语句的执行计划结果触发写操作


    背景

      某某同学执行了一下Explain结果结果发现数据库有了一条写入操作,恭喜这位同学你的锅到货了,你签收一下;

      对! 你没有听错,在一种场景下就算是Explain也会引发数据的写操作,就这是外层查询访问任意表,内层查询调用function

      在function有写入动作的情况下会发生写入。

    硬生生的套上一个场景

      假设我们有一个Person表,每访问一次Person表都记录一次在什么时候,访问了哪一行,表结构设计如下

    create table if not exists person(
        id int not null auto_increment primary key,
        name varchar(16)
    );
    
    create table if not exists person_opration_log(
        id int not null auto_increment primary key,
        pid int not null,
        access_datetime datetime
    );
    
    delimiter //
    create function fun_person_log(pid int) returns int
        begin
            insert into person_opration_log(pid,access_datetime) values(pid,now());
            return pid;
        end //
    
    delimiter ;

      正常的数据访问SQL如下,但是它并不写日志

    mysql> select
        ->     id,
        ->     name 
        -> from person 
        -> where id = 1;
    +----+--------+
    | id | name   |
    +----+--------+
    |  1 | 项羽   |
    +----+--------+
    1 row in set (0.00 sec)

      如果我们要写日志可以分两步走,先访问再计一笔日志

    mysql> select
        ->     id,
        ->     name 
        -> from person 
        -> where id = 1;
    +----+--------+
    | id | name   |
    +----+--------+
    |  1 | 项羽   |
    +----+--------+
    1 row in set (0.00 sec)
    
    mysql> 
    mysql> select fun_person_log(1);
    +-------------------+
    | fun_person_log(1) |
    +-------------------+
    |                 1 |
    +-------------------+
    1 row in set (0.05 sec)
    
    mysql> 
    mysql> select * from person_opration_log ;
    +----+-----+---------------------+
    | id | pid | access_datetime     |
    +----+-----+---------------------+
    |  1 |   1 | 2018-10-06 17:12:31 |
    +----+-----+---------------------+
    1 row in set (0.00 sec)

    牛人想出的新点子把两步合成一步

      牛人的新点子

    mysql> select 
        ->     fun_person_log(100) as id , 
        ->     name
        -> from person
        -> where id = (select fun_person_log(100));
    Empty set (0.04 sec)
    
    mysql> 
    mysql> select * from person_opration_log;
    +----+-----+---------------------+
    | id | pid | access_datetime     |
    +----+-----+---------------------+
    |  1 |   1 | 2018-10-06 17:12:31 |
    |  2 | 100 | 2018-10-06 17:15:29 |
    +----+-----+--------------------

      牛人的新点子刚好入坑,我们可以explain一下

    mysql> explain select 
        ->     fun_person_log(250) as id , 
        ->     name
        -> from person
        -> where id = (select fun_person_log(250));
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
    | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                          |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
    |  1 | PRIMARY     | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | no matching row in const table |
    |  2 | SUBQUERY    | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | No tables used                 |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
    2 rows in set, 1 warning (0.08 sec)
    
    mysql> 
    mysql> select * from person_opration_log;
    +----+-----+---------------------+
    | id | pid | access_datetime     |
    +----+-----+---------------------+
    |  1 |   1 | 2018-10-06 17:12:31 |
    |  2 | 100 | 2018-10-06 17:15:29 |
    |  3 | 250 | 2018-10-06 17:17:23 |
    +----+-----+---------------------+
    3 rows in set (0.00 sec)

      看吧! explain引发了写入操作!

    参考连接

    Derived Tables

    学习交流

     -----------------------------http://www.sqlpy.com-------------------------------------------------

     -----------------------------http://www.sqlpy.com-------------------------------------------------

      

  • 相关阅读:
    Silverlight搜索框 (Button inside TextBox)
    Silverlight的一个简单加载标志Loading...
    WCF “GenerateWcfClientFilesTask”任务意外失败
    C# 字符格式处理
    c# 链表结构(2)循环链表
    CSS技巧 — 不使用图片实现圆角、阴影、渐变等功能【转】
    Silverlight监听属性变化
    浅谈HTTP中Get与Post的区别 [转]
    asp.net本质论——HttpModule
    web.config文件自定义配置节的使用方法的一个简单例子
  • 原文地址:https://www.cnblogs.com/JiangLe/p/9747811.html
Copyright © 2020-2023  润新知