1. 程式人生 > >MySQL通過Explain查看select語句的執行計劃結果觸發寫操作

MySQL通過Explain查看select語句的執行計劃結果觸發寫操作

fun 學習交流 target emp tables HERE 背景 一次 time

背景

  某某同學執行了一下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-------------------------------------------------

  

MySQL通過Explain查看select語句的執行計劃結果觸發寫操作