[英]Can querying a TEXT column lead to creation of a temp table?
我不是很了解mysql。 因此,如果這是一個愚蠢的問題,請原諒。
我今天從數據庫管理員那里接到一個電話,說我的應用程序創建的臨時表數量激增。
除了我沒有明確創建任何臨時表。
在進行故障排除時,我們發現每次在子查詢中使用TEXT列時,都會創建一個臨時表。
作為開發人員,我發現使用子查詢和TEXT列創建了一個臨時表感到困惑。
我的問題是,作為開發人員,我如何才能理解QUERY何時會創建臨時表(在后台)。
我做了一些谷歌搜索,發現我可以做類似的事情
show GLOBAL status like 'created_tmp_disk_tables'
但是它告訴我什么? 我怎么知道我的查詢是否導致了臨時表。
要確定語句是否需要臨時表,請使用EXPLAIN並檢查Extra列以查看其是否顯示“使用臨時表”。
從文檔中 :
服務器在以下條件下創建臨時表:
評估UNION語句,但稍后會有一些例外。
評估某些視圖,例如使用TEMPTABLE算法,UNION或聚合的視圖。
派生表的評估(FROM子句中的子查詢)。
為子查詢或半聯接實現創建的表(請參見第9.2.1.18節“子查詢優化”)。
評估包含ORDER BY子句和另一個GROUP BY子句的語句,或者對於ORDER BY或GROUP BY包含聯接隊列中第一個表以外的表中的列的語句,進行評估。
結合ORDER BY對DISTINCT進行評估可能需要一個臨時表。
對於使用SQL_SMALL_RESULT選項的查詢,MySQL使用內存中臨時表,除非查詢還包含需要磁盤存儲的元素(稍后描述)。
評估多表UPDATE語句。
計算GROUP_CONCAT()或COUNT(DISTINCT)表達式。
同樣,某些查詢條件會阻止使用內存中的臨時表,在這種情況下,服務器將使用磁盤上的表來代替:
表中是否存在BLOB或TEXT列
GROUP BY或DISTINCT子句中存在任何字符串列,對於二進制字符串,大於512個字節,對於非二進制字符串,大於512個字符。 (這僅在MySQL 5.7.5之前適用。此外,在MySQL 5.7.3之前,無論字符串類型如何,該限制均為512字節。)
如果使用UNION或UNION ALL,則SELECT列表中存在任何最大長度大於512(字符串為二進制字符串,非二進制為字符)的字符串列
SHOW COLUMNS和DESCRIBE語句使用BLOB作為某些列的類型,因此用於結果的臨時表是磁盤上的表。
MySQL在很多不同類型的查詢中使用臨時表,而無需您查詢它們。 經常(但並非總是)創建臨時表的幾種情況:
GROUP BY
UNION
VIEW
查詢 WITH ...
語法) 在文檔中可以找到關於MySQL使用“內部”臨時表的更完整指南: https : //dev.mysql.com/doc/refman/5.7/en/internal-temporary-tables.html
基本上,當執行查詢需要保存部分結果中的行,然后繼續將部分結果細化為最終結果時,將使用臨時表。
臨時表對於使用MYSQL Server而言相當昂貴,因此我們希望盡可能避免使用它們。 當臨時表寫入文件系統而不是保留在內存中時,尤其昂貴。 當臨時表涉及TEXT
或BLOB
列,或者它需要存儲的行超出tmp_table_size
配置選項所限制的內存量時,就會發生這種情況。
您可以(大部分)通過使用EXPLAIN
分析查詢來確定查詢何時將使用臨時表。 參見https://dev.mysql.com/doc/refman/5.7/en/explain.html
有時內部臨時表是不可避免的,因為沒有其他方法可以獲取所需的查詢結果。 但是有時您可以重寫SQL查詢或使用索引來幫助查詢獲得相同的結果,而無需使用臨時表。 它取決於特定的查詢和您的表定義。 查詢優化是必須根據具體情況進行的過程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.