MySQL通過Explain查看select語句的執行計劃結果觸發寫操作
阿新 • • 發佈:2018-10-06
fun 學習交流 target emp tables HERE 背景 一次 time
【背景】
某某同學執行了一下Explain結果結果發現數據庫有了一條寫入操作,恭喜這位同學你的鍋到貨了,你簽收一下;
對! 你沒有聽錯,在一種場景下就算是Explain也會引發數據的寫操作,就這是外層查詢訪問任意表,內層查詢調用function
在function有寫入動作的情況下會發生寫入。
【硬生生的套上一個場景】
假設我們有一個Person表,每訪問一次Person表都記錄一次在什麽時候,訪問了哪一行,表結構設計如下
create table if not exists person( id int not null auto_increment primarykey, 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語句的執行計劃結果觸發寫操作