簡體   English   中英

MySQL“正在使用臨時”,但此查詢中沒有匹配的正式原因

[英]Mysql “Using temporary” but no official reason matched in this query

如果您查看MySql臨時表的官方文檔:

http://dev.mysql.com/doc/refman/5.1/en/internal-temporary-tables.html

給出的原因有:

   The server creates temporary tables under conditions such as these:

      Evaluation of UNION statements.

      Evaluation of some views, such those that use the TEMPTABLE algorithm,
      UNION, or aggregation.

      Evaluation of statements that contain an ORDER BY clause and a
      different GROUP BY clause, or for which the ORDER BY or GROUP BY
      contains columns from tables other than the first table in the join queue.

      Evaluation of DISTINCT combined with ORDER BY may require a temporary table.

      For queries that use the SQL_SMALL_RESULT option, MySQL uses an
      in-memory temporary table, unless the query also contains elements
      (described later) that require on-disk storage.

      Evaluation of multiple-table UPDATE statements.

      Evaluation of GROUP_CONCAT() or COUNT(DISTINCT) expressions. 

此查詢均不滿足以下條件:

  select ttl.id AS id,
  ttl.name AS name,
  ttl.updated_at AS last_update_on,
  ttl.user_id AS list_creator,
  ttl.retailer_nomination_list AS nomination_list,
  ttl.created_at AS created_on,
  tv.name AS venue_name,
  from haha_title_lists ttl 
    left join haha_title_list_to_users tltu on  ((ttl.id = tltu.title_list_id))
    left join users u on  ((tltu.user_id = u.id)) 
    left join users u2 on  ((tltu.user_id = u2.id)) 
    left join haha_title_list_to_venues tlv on  ((ttl.id = tlv.title_list)) 
    left join haha_venue_properties tvp on  ((tlv.venue_id = tvp.id)) 
    left join haha_venues tv on  ((tvp.venue_id = tv.id))
    join haha_title_list_to_books tlb on  ((ttl.id = tlb.title_list_id))
    join wawa_title ot on  ((tlb.title_id = ot.title_id))
    join wawa_title_to_author ota on  ((ot.title_id = ota.title_id))
    join wawa_author oa on  ((ota.author_id = oa.author_id))
    group by ttl.id;

對於此表:

  CREATE TABLE  haha_title_lists  (
     id  int(11) unsigned NOT NULL AUTO_INCREMENT,
     name  varchar(255) DEFAULT NULL,
     isbn  varchar(15) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
     created_at  datetime NOT NULL,
     updated_at  datetime NOT NULL,
     user_id  int(11) DEFAULT NULL,
     list_note  text,
     retailer_nomination_list  int(11) DEFAULT NULL,
    PRIMARY KEY ( id )
  ) ENGINE=InnoDB AUTO_INCREMENT=460 DEFAULT CHARSET=utf8

我希望使用PRIMARY KEY,因為此表僅在id上匹配。 什么會導致使用臨時表?

如果我對此查詢運行EXPLAIN,則會得到:

    +----+-------------+-------+--------+------------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------+------+---------------------------------+
  | id | select_type | table | type   | possible_keys                                                          | key                                   | key_len | ref                                   | rows | Extra                           |
  +----+-------------+-------+--------+------------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------+------+---------------------------------+
  |  1 | SIMPLE      | ttl   | ALL    | PRIMARY                                                                | NULL                                  | NULL    | NULL                                  |  307 | Using temporary; Using filesort |
  |  1 | SIMPLE      | tltu  | ref    | idx_title_list_to_user                                                 | idx_title_list_to_user                | 4       | wawa_ripple_development.ttl.id        |    1 | Using index                     |
  |  1 | SIMPLE      | u     | eq_ref | PRIMARY                                                                | PRIMARY                               | 4       | wawa_ripple_development.tltu.user_id  |    1 | Using index                     |
  |  1 | SIMPLE      | u2    | eq_ref | PRIMARY                                                                | PRIMARY                               | 4       | wawa_ripple_development.tltu.user_id  |    1 | Using index                     |
  |  1 | SIMPLE      | tlb   | ref    | idx_title_list_to_books_title_id,idx_title_list_to_books_title_list_id | idx_title_list_to_books_title_list_id | 4       | wawa_ripple_development.ttl.id        |   49 | Using where                     |
  |  1 | SIMPLE      | ot    | eq_ref | PRIMARY                                                                | PRIMARY                               | 4       | wawa_ripple_development.tlb.title_id  |    1 | Using index                     |
  |  1 | SIMPLE      | ota   | ref    | PRIMARY,title_id                                                       | title_id                              | 4       | wawa_ripple_development.ot.title_id   |    1 | Using where; Using index        |
  |  1 | SIMPLE      | oa    | eq_ref | PRIMARY                                                                | PRIMARY                               | 4       | wawa_ripple_development.ota.author_id |    1 | Using index                     |
  |  1 | SIMPLE      | tlv   | ALL    | NULL                                                                   | NULL                                  | NULL    | NULL                                  |  175 |                                 |
  |  1 | SIMPLE      | tvp   | eq_ref | PRIMARY                                                                | PRIMARY                               | 4       | wawa_ripple_development.tlv.venue_id  |    1 |                                 |
  |  1 | SIMPLE      | tv    | eq_ref | PRIMARY                                                                | PRIMARY                               | 4       | wawa_ripple_development.tvp.venue_id  |    1 |                                 |
  +----+-------------+-------+--------+------------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------+------+---------------------------------+

為什么會出現“使用臨時;使用文件排序”的提示?

首先,一些評論...

“使用臨時文件,使用文件排序”通常位於EXPLAIN的第一行,但是它們的實際位置可以在任何地方。 此外, 甚至對於一個表的查詢,可能會有多個 tmp和/或排序。 例如: ... GROUP BY aaa ORDER BY bbb可能使用一個tmp進行分組,而使用另一個tmp進行排序。

在較新的版本中,您可以執行EXPLAIN FORMAT=JSON SELECT...以獲得逐項打擊帳戶-顯然那里有多少個tmp和排序。

“文件排序”是用詞不當。 在許多情況下,數據實際上可能收集在內存中並在那里進行排序。 即,“在查詢的拍攝中沒有文件受到損害”。 有很多原因決定(預先或以后)使用基於磁盤的排序。 我不會在此答案中提供這些詳細信息。 一種檢查方法是SHOW STATUS LIKE 'Created_tmp%tables'; 另一個是通過慢日志。

直到最近UNIONs 某些 UNIONs進行了改進,以避開tmp表-在明顯不需要它們的明顯情況下。 union,聯合仍然是單線程的。

回到您的問題...是的,您的GROUP BY適用於第一個表。 但是,無論出於何種原因,優化器都選擇收集數據,然后進行排序。 另一個選擇是使用PRIMARY KEY(id)進行排序和分組。 嗯...我想知道如果您添加ORDER BY ttl.id會發生什么? 我猜測優化器將重點放在如何進行GROUP BY (通過文件排序還是通過在ram中收集哈希值),並決定所有JOINs都考慮JOINs

暫無
暫無

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

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