sql臨時表效率
⑴ sql 臨時表創建索引會提高效率嗎
只要你索引設置合理,當然會提升效率,其實臨時表你也可以理解為存儲在TempDB資料庫中的物理表。
我在做復雜業務流程處理時,經常用到臨時表,這樣就能避免對原始大數據表的頻繁檢索,明顯對速度有提升
⑵ sql 如何用臨時表優化性能
InnoDB 類型的臨時表存在的潛在問題
盡管使用 InnoDB 是性能最佳的,但可能會出現新的潛在問題。在某些特定情況下,您可能會出現磁碟耗盡和伺服器中斷。
與資料庫中的任何其他 InnoDB 表一樣,臨時表具有自己的表空間文件。新文件與通用表空間一起位於數據目錄中,名稱為 ibtmp1。它存儲所有 tmp 表。不運行手動運行 OPTIMIZE TABLE,表空間文件就會不斷增長。如果你不能使用 OPTIMIZE,那麼唯一能將 ibtmp1 大小縮小為零的方法,就是重新啟動伺服器。幸運的是,即使文件無法減小,在執行查詢後,臨時表也會自動刪除,表空間可回收使用。現在,我們想一想以下情境:
存在未優化的查詢,需要在磁碟上創建非常大的的臨時表
存在優化的查詢,但他們正在磁碟上創建非常大的臨時表,因為你正在對此數據集進行計算(統計,分析)
高並發連接時,運行相同的查詢,伴隨臨時表的創建
沒有很多可用空間
- 在這些情況下,文件 ibtmp1 大大增加,很容易耗盡可用空間。這種情況每天發生幾次,並且必須重啟伺服器才能完全縮小 ibtmp1 表空間。使用不可收縮的文件可以輕松耗盡磁碟空間!
- 雖然可以暫時解決問題,但這不是最佳解決方案。實際上,您可以通過逐步增加磁碟大小,來猜測具體需要的空間。如果環境位於雲中,或者在非常大的虛擬平台,這很容易實現。但是使用這種解決方案,您可能會面臨不必要的開支。您還可以通過設置以下配置變數將 ibtmp1 文件移動到專用大型磁碟上: [mysqld] innodb_temp_data_file_path = ../../tmp/ibtmp1:12M:autoextend
- 例如: [mysqld] innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:10G
- 退回 MyISAM 將臨時表存儲在磁碟上
- internal_tmp_disk_storage_engine = MYISAM
- 由於變數是動態的,您也可以在運行時設置它: SET GLOBAL internal_tmp_disk_storage_engine = MYISAM;
- 回到 MyISAM,您將大大降低寫滿磁碟空間的可能性。實際上,臨時表將創建到不同的文件中,並在查詢結束時立即刪除。
- 在將存儲引擎退回到 MyISAM 以減輕中斷發生後,必須花時間分析查詢。目標是減小磁碟上臨時表的大小。本文的目的不是解釋如何調查查詢,而是可以依賴慢速日誌,像 pt-query-digest 和 EXPLAIN 這樣的工具。一些技巧:
在表上創建缺少的索引
如果不需要,可以在查詢中添加更多過濾條件以更少收集的數據
重寫查詢以優化執行計劃
可以在應用程序中使用隊列管理器來序列化它們的執行或減少並發性
那麼,如何避免磁碟耗盡和中斷呢?
簡單的解決方案:使用更大的磁碟
需要重啟 MySQL 。注意,必須將路徑指定為相對於數據目錄。
設置 ibtmp1 大小的上限
在這種情況下,文件不能超過 10GB。可以降低宕機概率,但也是一個危險的解決方案。當數據文件達到最大值時,會查詢失敗並顯示一個錯誤,提示表已滿。
這個解決方案似乎違反直覺,但它可能是快速避免中斷的最佳方法,並保證使用所有需要的臨時表。
雖然總是有可能看到相同的問題,以防你可以在同一時間運行查詢或非常接近。在我的實際案例中,這是避免所有中斷的解決方案。
優化你的查詢
但希望在所有優化之後,您可以返回將臨時存儲引擎設置為 InnoDB 以獲得更好的性能。
結論
有時這些改進會產生意想不到的副作用。用於磁碟上臨時表的 InnoDB 存儲引擎是一個很好的改進,但在某些特定情況下,例如,如果您有未優化查詢和很少的可用空間,則可能因「磁碟已滿」錯誤而中斷。將 tmp 存儲引擎退回到 MyISAM 是避免中斷的最快方法,但是為了返回到 InnoDB,查詢的優化是更重要的事情。更大或專用的磁碟也可能有所幫助。但這是一個微不足道的建議。