国产探花免费观看_亚洲丰满少妇自慰呻吟_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來改進,另外一種則是盡可能避免使用。

(編輯:武林網)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 确山县| 上饶县| 上蔡县| 无为县| 耒阳市| 金阳县| 黔西县| 福安市| 拉萨市| 锡林浩特市| 宝清县| 西昌市| 六安市| 开江县| 大田县| 壶关县| 荣昌县| 甘德县| 衡水市| 盱眙县| 昌邑市| 丽江市| 临夏县| 开江县| 突泉县| 麦盖提县| 三穗县| 商洛市| 准格尔旗| 陇川县| 曲阳县| 扎兰屯市| 驻马店市| 大英县| 弥勒县| 石棉县| 上栗县| 察雅县| 静乐县| 信宜市| 志丹县|