簡體   English   中英

查詢TEXT列可以導致創建臨時表嗎?

[英]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而言相當昂貴,因此我們希望盡可能避免使用它們。 當臨時表寫入文件系統而不是保留在內存中時,尤其昂貴。 當臨時表涉及TEXTBLOB列,或者它需要存儲的行超出tmp_table_size配置選項所限制的內存量時,就會發生這種情況。

您可以(大部分)通過使用EXPLAIN分析查詢來確定查詢何時將使用臨時表。 參見https://dev.mysql.com/doc/refman/5.7/en/explain.html

有時內部臨時表是不可避免的,因為沒有其他方法可以獲取所需的查詢結果。 但是有時您可以重寫SQL查詢或使用索引來幫助查詢獲得相同的結果,而無需使用臨時表。 它取決於特定的查詢和您的表定義。 查詢優化是必須根據具體情況進行的過程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM