国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

MySQL內的derived table

2024-07-24 12:31:48
字體:
來源:轉載
供稿:網友
        初始MySQL中的derived table還是在一個偶然的問題場景中。
 
        下面的語句在執行的時候拋出了錯誤。
 
UPDATE payment_data rr
   SET rr.penalty_date = '2017-4-12'
 where rr.id =
       (SELECT min(r.id)
          FROM payment_data r
         where data_no =
               (SELECT data_no
                  FROM user_debt
                 WHERE out_trade_no = 'bestpay_order_no1491812746329'));
 
ERROR 1093 (HY000): You can't specify target table 'rr' for update in FROM clause    如果對MySQL查詢優化器足夠了解就會明白,其實這種方式是MySQL不支持的,有沒有WA呢,還是有的,那就是通過一種特殊的子查詢來完成,也就是derived table
 
所以上面的語句使用如下的方式就可以破解。
 
UPDATE payment_data rr
   SET rr.penalty_date = '2017-4-12'
 where rr.id =
       (SELECT min(t.id)
          FROM (select id,data_no from payment_data r) t
         where t.data_no =
               (SELECT data_no
                  FROM user_debt
                 WHERE out_trade_no = 'bestpay_order_no1491812746329'));
我們回到剛剛提到的Derived table,在官方文檔中是這么說的。
 
第一種:
 
> select * from (select id from t_fund_info) t where t.id=138031;
1 row in set (1.12 sec)這個時候查看執行計劃,就會看到derived table的字樣。
 
> explain select * from (select id from t_fund_info) t where t.id=138031;
+----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+
| id | select_type | table       | type  | possible_keys | key     | key_len | ref  | rows    | Extra       |
+----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+
|  1 | PRIMARY     | <derived2>  | ALL   | NULL          | NULL    | NULL    | NULL | 1998067 | Using where |
|  2 | DERIVED     | t_fund_info | index | NULL          | account | 182     | NULL | 2127101 | Using index |
+----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+
2 rows in set (0.90 sec)看起來是1秒的執行速度,差別還不是很大,我們換第二種方式。
 
>  select * from (select * from t_fund_info) t where t.id=138031;
ERROR 126 (HY000): Incorrect key file for table '/tmp/#sql_3e34_0.MYI'; try to repair it
這個時候就會發現這么一個看似簡單的查詢竟然拋出了錯誤。
 
查看錯誤里的信息,是一個MYI的文件,顯然是使用了臨時表的方式,典型的一個myisam表。
 
為了驗證這個過程,我盡可能完整的收集了/tmp目錄下的文件使用情況,可以看到,占用了2G多的空間,最后發現磁盤空間不足退出。
 
# df -h|grep //tmp
/dev/shm              6.0G  4.1G  1.6G  73% /tmp
/dev/shm              6.0G  4.5G  1.2G  79% /tmp
/dev/shm              6.0G  4.8G  903M  85% /tmp
/dev/shm              6.0G  4.9G  739M  88% /tmp
/dev/shm              6.0G  5.0G  625M  90% /tmp
/dev/shm              6.0G  5.2G  498M  92% /tmp
/dev/shm              6.0G  5.3G  386M  94% /tmp
/dev/shm              6.0G  5.4G  250M  96% /tmp
/dev/shm              6.0G  5.5G  110M  99% /tmp
/dev/shm              6.0G  5.7G  4.0K 100% /tmp
/dev/shm              6.0G  3.7G  2.0G  66% /tmp
/dev/shm              6.0G  3.7G  2.0G  66% /tmp這里有另外一個疑問,那就是這個表t_fund_info是個InnoDB表,占用空間是400M左右,但是derived table使用率竟然達到了2G以上,不知道MySQL內部是怎么進一步處理的。
  
執行計劃和主鍵的執行計劃一模一樣。
 
所以對于derived table的改進方式,一種是通過view來改進,另外一種則是盡可能避免使用。

(編輯:武林網)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 临西县| 鹿泉市| 宁陵县| 郓城县| 维西| 综艺| 安顺市| 保山市| 镇江市| 青阳县| 中超| 教育| 尚志市| 微山县| 永兴县| 安义县| 桐庐县| 安徽省| 万载县| 龙川县| 炎陵县| 福鼎市| 灵山县| 承德市| 唐山市| 昌江| 大化| 洪泽县| 长宁区| 肥东县| 绥中县| 宿迁市| 新源县| 昭通市| 广东省| 临泉县| 甘肃省| 出国| 格尔木市| 张家港市| 汝州市|