{"id":644,"date":"2015-02-24T13:47:27","date_gmt":"2015-02-24T12:47:27","guid":{"rendered":"http:\/\/dbahire.com\/?p=644"},"modified":"2019-08-27T12:00:17","modified_gmt":"2019-08-27T10:00:17","slug":"regarding-mysql-5-6-temporary-tables-format","status":"publish","type":"post","link":"https:\/\/jynus.com\/dbahire\/regarding-mysql-5-6-temporary-tables-format\/","title":{"rendered":"Regarding MySQL 5.6 temporary tables format"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/jynus.com\/dbahire\/wp-content\/uploads\/2015\/02\/temporary-table.png\" alt=\"A temporary table\" title=\"This is clearly a metaphor for a MySQL temporary table and not a SEO trick\" class=\"alignright size-full wp-image-645\" width=\"280\" height=\"300\"><code>default_tmp_storage_engine<\/code> variable was introduced in 5.6.3, allowing the configuration of the default engine for temporary tables. This seems to be in the direction, as I commented before, of <a href=\"https:\/\/jynus.com\/dbahire\/today-is-the-day-in-which-myisam-is-no-longer-needed\/\" title=\"Today is the day in which MyISAM is no longer needed\">making MyISAM an optional engine<\/a>. In 5.7, <a href=\"https:\/\/blogs.oracle.com\/mysqlinnodb\/entry\/https_blogs_oracle_com_mysqlinnodb\">a separate tablespace is being created to hold those tables in order to reduce its performance penalty<\/a> (those tables do not need to be redone if the server crashes, so extra writes are avoided).<\/p>\n<p>However, I have seen many people assuming that because <code>default_tmp_storage_engine<\/code> has the value &#8220;InnoDB&#8221;, all temporary tables are created in InnoDB format <em>in 5.6<\/em>. This is not true: first, because <strong>implicit temporary tables are still being created in memory using the <code>MEMORY<\/code> engine (sometimes called the <code>HEAP<\/code> engine), while MyISAM is being used for on-disk tables<\/strong>. If you do not trust the reference manual on this, here it is a quick test to check it:<\/p>\n<p><code>mysql&gt; SELECT version();<br \/>\n+------------+<br \/>\n| version()  |<br \/>\n+------------+<br \/>\n| 5.6.23-log |<br \/>\n+------------+<br \/>\n1 row in set (0.00 sec)<\/code><\/p>\n<p><code>mysql&gt; SHOW GLOBAL VARIABLES like 'default%';<br \/>\n+----------------------------+--------+<br \/>\n| Variable_name              | Value  |<br \/>\n+----------------------------+--------+<br \/>\n| default_storage_engine     | InnoDB |<br \/>\n| default_tmp_storage_engine | InnoDB |<br \/>\n| default_week_format        | 0      |<br \/>\n+----------------------------+--------+<br \/>\n3 rows in set (0.00 sec)<\/code><\/p>\n<p><code>mysql&gt; SHOW GLOBAL VARIABLES like 'tmpdir';<br \/>\n+---------------+-------+<br \/>\n| Variable_name | Value |<br \/>\n+---------------+-------+<br \/>\n| tmpdir        | \/tmp  |<br \/>\n+---------------+-------+<br \/>\n1 row in set (0.00 sec)<\/p>\n<p>mysql&gt; CREATE TABLE test (id serial, a text);<br \/>\nQuery OK, 0 rows affected (0.10 sec)<\/p>\n<p>mysql&gt; insert into test (a) values ('a');<br \/>\nQuery OK, 1 row affected (0.06 sec)<\/p>\n<p>mysql&gt; insert into test (a) values ('aa');<br \/>\nQuery OK, 1 row affected (0.00 sec)<\/p>\n<p>mysql&gt; insert into test (a) values ('aaa');<br \/>\nQuery OK, 1 row affected (0.00 sec)<\/p>\n<p>mysql&gt; SELECT *, sleep(10) FROM test ORDER BY rand();<br \/>\n...<\/p>\n<p>[ec2-user@jynus_com tmp]$ ls -la<br \/>\ntotal 24<br \/>\ndrwxrwxrwt  5 root     root     4096 Feb 24 11:55 .<br \/>\ndr-xr-xr-x 23 root     root     4096 Jan 28 14:09 ..<br \/>\ndrwxrwxrwt  2 root     root     4096 Jan 28 14:09 .ICE-unix<br \/>\n-rw-rw----  1 mysql    mysql       0 Feb 24 11:55 #sql_7bbd_0.MYD<br \/>\n-rw-rw----  1 mysql    mysql    1024 Feb 24 11:55 #sql_7bbd_0.MYI<br \/>\ndrwx------  2 ec2-user ec2-user 4096 Feb 24 11:41 ssh-5ZGoXWFwtQ<br \/>\ndrwx------  2 ec2-user ec2-user 4096 Feb 24 11:43 ssh-w9IkW0SvYo<\/p>\n<p><\/code><code><\/code><code>...<br \/>\n+----+------+-----------+<br \/>\n| id | a    | sleep(10) |<br \/>\n+----+------+-----------+<br \/>\n|  1 | a    |         0 |<br \/>\n|  2 | aa   |         0 |<br \/>\n|  3 | aaa  |         0 |<br \/>\n+----+------+-----------+<br \/>\n3 rows in set (30.00 sec)<br \/>\n<\/code><\/p>\n<p>The only thing I have done above is forcing the creation of the temporary table on disk by adding a TEXT field (incompatible with the MEMORY engine, so it has to be created on disk) and using sleep so that we have enough time to check the filesystem. You can see on the output of <code>ls<\/code> the .MYD and .MYI particular to the MyISAM engine. That last step would be unnecessary if we just used <code>PERFORMANCE_SCHEMA<\/code> to check the <code>waits\/io<\/code>.<\/p>\n<p>A second, and more obvious reason why thinking that all temporary tables are created in InnoDB format, is because <strong>explicit temporary tables <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/create-table.html\">can still be created in a different engine<\/a> with the ENGINE keyword<\/strong>:<\/p>\n<p><code>mysql&gt; CREATE TEMPORARY TABLE test (i serial) ENGINE=MyISAM;<br \/>\nQuery OK, 0 rows affected (0.00 sec)<\/code><\/p>\n<p><code>[ec2-user@jynus_com tmp]$ ls -la<br \/>\ntotal 36<br \/>\ndrwxrwxrwt  5 root     root     4096 Feb 24 12:16 .<br \/>\ndr-xr-xr-x 23 root     root     4096 Jan 28 14:09 ..<br \/>\ndrwxrwxrwt  2 root     root     4096 Jan 28 14:09 .ICE-unix<br \/>\n-rw-rw----  1 mysql    mysql    8554 Feb 24 12:12 #sql7bbd_36a3_0.frm<br \/>\n-rw-rw----  1 mysql    mysql       0 Feb 24 12:12 #sql7bbd_36a3_0.MYD<br \/>\n-rw-rw----  1 mysql    mysql    1024 Feb 24 12:12 #sql7bbd_36a3_0.MYI<br \/>\ndrwx------  2 ec2-user ec2-user 4096 Feb 24 11:41 ssh-5ZGoXWFwtQ<br \/>\ndrwx------  2 ec2-user ec2-user 4096 Feb 24 11:43 ssh-w9IkW0SvYo<\/code><\/p>\n<p><code>mysql&gt; DROP TEMPORARY TABLE test;<br \/>\nQuery OK, 0 rows affected (0.00 sec)<\/p>\n<p><\/code><code><\/code><code>[ec2-user@jynus_com tmp]$ ls -la<br \/>\ntotal 20<br \/>\ndrwxrwxrwt  5 root     root     4096 Feb 24 12:17 .<br \/>\ndr-xr-xr-x 23 root     root     4096 Jan 28 14:09 ..<br \/>\ndrwxrwxrwt  2 root     root     4096 Jan 28 14:09 .ICE-unix<br \/>\ndrwx------  2 ec2-user ec2-user 4096 Feb 24 11:41 ssh-5ZGoXWFwtQ<br \/>\ndrwx------  2 ec2-user ec2-user 4096 Feb 24 11:43 ssh-w9IkW0SvYo<br \/>\n<\/code><\/p>\n<p>Will this change in the future? 5.7.5 continues to have the same behavior as 5.6. However, as <a href=\"https:\/\/www.flamingspork.com\/blog\/2013\/04\/26\/a-few-notes-on-innodb-in-mysql-5-7-1\/\">Stewart pointed some time ago<\/a>, the performance optimizations in 5.7 make some uses of MEMORY and MyISAM obsolete so I will not be surprised if that dependency, together with MyISAM grant tables, will be removed in the future.<\/p>\n<p><strong>Update:<\/strong> I&#8217;ve been told by email by <a href=\"http:\/\/www.tocker.ca\/\">Morgan<\/a> that the yet-to-be-released (at the time of this writing) 5.7.6 will finally change the default behavior to be full InnoDB for implicit temporary tables, too, as seen on the <a href=\"http:\/\/dev.mysql.com\/doc\/relnotes\/mysql\/5.7\/en\/news-5-7-6.html\">release notes<\/a>:<\/p>\n<blockquote><p>InnoDB: The default setting for the internal_tmp_disk_storage_engine option, which defines the storage engine the server uses for on-disk internal temporary tables (see How MySQL Uses Internal Temporary Tables), is now INNODB. With this change, the Optimizer uses the InnoDB storage engine instead of MyISAM for internal temporary tables.<\/p><\/blockquote>\n<p><code>internal_tmp_disk_storage_engine<\/code> was introduced in 5.7.5, but its default value then was MYISAM.<\/p>\n<p>This is in order to get advantage of the in-memory performance of InnoDB for variable-lengh fields, which I am personally 100% for. Thank you Morgan for the extra information!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>default_tmp_storage_engine variable was introduced in 5.6.3, allowing the configuration of the default engine for temporary tables. This seems to be in the direction, as I commented before, of making MyISAM an optional engine. In 5.7, a separate tablespace is being<\/p>\n","protected":false},"author":1,"featured_media":645,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16],"tags":[33,151,283,125,281,32,279,53,285,277,275,273],"class_list":["post-644","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mysql","tag-5-6","tag-5-7","tag-engine","tag-format","tag-heap","tag-innodb","tag-memory","tag-myisam","tag-primary-en","tag-tables","tag-temporary","tag-tmp"],"_links":{"self":[{"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts\/644","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/comments?post=644"}],"version-history":[{"count":12,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts\/644\/revisions"}],"predecessor-version":[{"id":1002,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts\/644\/revisions\/1002"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/media\/645"}],"wp:attachment":[{"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/media?parent=644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/categories?post=644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/tags?post=644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}