<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Alexander Rubin&#039;s Blog on MySQL &#187; temporary tables</title>
	<atom:link href="http://www.arubin.org/blog/category/temporary-tables/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.arubin.org/blog</link>
	<description>MySQL, FullText Search, Performance, High Availability</description>
	<lastBuildDate>Sat, 30 Jul 2011 00:18:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using MySQL 5.6 to find queries creating disk temporary tables</title>
		<link>http://www.arubin.org/blog/2011/05/01/using-mysql-5-6-to-find-queries-creating-disk-temporary-tables/</link>
		<comments>http://www.arubin.org/blog/2011/05/01/using-mysql-5-6-to-find-queries-creating-disk-temporary-tables/#comments</comments>
		<pubDate>Sun, 01 May 2011 23:58:10 +0000</pubDate>
		<dc:creator>arubin</dc:creator>
				<category><![CDATA[performance tuning]]></category>
		<category><![CDATA[temporary tables]]></category>
		<category><![CDATA[disk temporary tables]]></category>
		<category><![CDATA[mysql 5.6]]></category>
		<category><![CDATA[performance_schema]]></category>
		<category><![CDATA[slow query]]></category>

		<guid isPermaLink="false">http://www.arubin.org/blog/?p=98</guid>
		<description><![CDATA[<p>In my previous post, I&#8217;ve showed how to use Dtrace to find queries creating disk temporary tables (only available for OS with dtrace: solaris, freebsd, etc). </p>
<p>In MySQL 5.6 (which is not released yet, use &#8220;labs&#8221; version for now) we can use new performance_schema table events_statements_history or events_statements_history_long to find all performance metrics for all [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous post, I&#8217;ve showed how to use Dtrace to <a href="http://www.arubin.org/blog/2009/10/02/using-dtrace-to-find-queries-creating-disk-temporary-tables/">find queries creating disk temporary tables</a> (only available for OS with dtrace: solaris, freebsd, etc). </p>
<p>In MySQL 5.6 (which is not released yet, use &#8220;labs&#8221; version for now) we can use new performance_schema table events_statements_history or events_statements_history_long to find all performance metrics for all queries including created disk/memory tables, use of index, etc. WOW! This is what I have been waiting for a long time!</p>
<p>To illustrate, I have grabbed mysql-5.6.3-labs-performance-schema-linux2.6-x86_64.tar.gz from <a href="http://labs.mysql.com/">labs.mysql.com</a> (this feature is only in labs version) and run sysbench readonly test (you need to disable prepared statements in sysbench, seems to be not working with prepared statements, I will check it later).</p>
<p>Here are the results:</p>
<blockquote>
<pre>mysql> select * from events_statements_history_long where  CREATED_TMP_DISK_TABLES > 0 limit 10\G
*************************** 10. row ***************************
              THREAD_ID: 74
               EVENT_ID: 3295633
             EVENT_NAME: statement/sql/select
                 SOURCE: sql_parse.cc:935
            TIMER_START: 633828149000000
              TIMER_END: 633843868000000
             TIMER_WAIT: 15719000000
              LOCK_TIME: 53000000
               SQL_TEXT: SELECT DISTINCT c from sbtest where id between 847399 and 847499 order by c
         CURRENT_SCHEMA: sbtest
            OBJECT_TYPE: NULL
          OBJECT_SCHEMA: NULL
            OBJECT_NAME: NULL
  OBJECT_INSTANCE_BEGIN: NULL
            MYSQL_ERRNO: 0
      RETURNED_SQLSTATE: NULL
           MESSAGE_TEXT: NULL
                 ERRORS: 0
               WARNINGS: 0
          ROWS_AFFECTED: 0
              ROWS_SENT: 1
          ROWS_EXAMINED: 103
CREATED_TMP_DISK_TABLES: 1
     CREATED_TMP_TABLES: 1
       SELECT_FULL_JOIN: 0
 SELECT_FULL_RANGE_JOIN: 0
           SELECT_RANGE: 1
     SELECT_RANGE_CHECK: 0
            SELECT_SCAN: 0
      SORT_MERGE_PASSES: 0
             SORT_RANGE: 0
              SORT_ROWS: 1
              SORT_SCAN: 1
          NO_INDEX_USED: 0
     NO_GOOD_INDEX_USED: 0
       NESTING_EVENT_ID: NULL
     NESTING_EVENT_TYPE: NULL
10 rows in set (0.00 sec)
</pre>
</blockquote>
<p>Or if you need only list of queries:</p>
<blockquote><pre>
mysql> select sql_text, count(*) as cnt  from events_statements_history_long
where  CREATED_TMP_DISK_TABLES > 0
group by sql_text order by cnt desc  limit 10;
+-----------------------------------------------------------------------------+-----+
| sql_text                                                                    | cnt |
+-----------------------------------------------------------------------------+-----+
| SELECT DISTINCT c from sbtest where id between 242012 and 242112 order by c |   2 |
| SELECT DISTINCT c from sbtest where id between 797388 and 797488 order by c |   2 |
| SELECT DISTINCT c from sbtest where id between 973150 and 973250 order by c |   1 |
| SELECT DISTINCT c from sbtest where id between 478783 and 478883 order by c |   1 |
| SELECT DISTINCT c from sbtest where id between 967035 and 967135 order by c |   1 |
| SELECT DISTINCT c from sbtest where id between 602102 and 602202 order by c |   1 |
| SELECT DISTINCT c from sbtest where id between 123827 and 123927 order by c |   1 |
| SELECT DISTINCT c from sbtest where id between 980527 and 980627 order by c |   1 |
| SELECT DISTINCT c from sbtest where id between 450354 and 450454 order by c |   1 |
| SELECT DISTINCT c from sbtest where id between 674804 and 674904 order by c |   1 |
+-----------------------------------------------------------------------------+-----+
10 rows in set (0.04 sec)
</pre>
</blockquote>
<p>We can filter and order by rows_examined,  SORT_MERGE_PASSES,  NO_INDEX_USED,  NO_GOOD_INDEX_USED, etc.</p>
<p>Links:</p>
<ul>
<li><a href="http://dev.mysql.com/tech-resources/articles/whats-new-in-mysql-5.6.html">What is new in MySQL 5.6: all long waited great features of MySQL 5.6</a> (btw: Multi-Threaded Slaves are coming up, now in labs only)</li>
<li><a href="http://www.markleith.co.uk/?p=471">A Big Bag of Epic Awesomeness</a>, by Mark Leith</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.arubin.org/blog/2011/05/01/using-mysql-5-6-to-find-queries-creating-disk-temporary-tables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Dtrace to find queries creating disk temporary tables</title>
		<link>http://www.arubin.org/blog/2009/10/02/using-dtrace-to-find-queries-creating-disk-temporary-tables/</link>
		<comments>http://www.arubin.org/blog/2009/10/02/using-dtrace-to-find-queries-creating-disk-temporary-tables/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 18:44:52 +0000</pubDate>
		<dc:creator>arubin</dc:creator>
				<category><![CDATA[dtrace]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[performance tuning]]></category>
		<category><![CDATA[temporary tables]]></category>

		<guid isPermaLink="false">http://www.arubin.org/blog/?p=36</guid>
		<description><![CDATA[Showed script with Dtrace to find queries creating disk temporary tables [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes we have a lots of small and rather fast queries which use group by/order by, thus creating temporary tables. Some of those queries are retrieving text fields and mysql have to use disk (myisam) temporary tables. Those queries usually run for less than 1-2 seconds, so they did not get into slow query log, however, they sometimes add serious load on the system.</p>
<p>Here is the stat example:</p>
<pre>
bash-3.00$  /usr/local/mysql/bin/mysqladmin -uroot -p -i 2 -r extended-status|grep tmp_disk
...
| Created_tmp_disk_tables           | 109           |
| Created_tmp_disk_tables           | 101           |
| Created_tmp_disk_tables           | 122           |
...
</pre>
<p>40-50 tmp_disk_tables created per second</p>
<p>So, how can we grab those queries? Usually we have to temporary enable general log, filter out queries with &#8220;group by/order by&#8221; and profile them all. On solaris/mac we can use dtrace instead.</p>
<p>Here is the simple script, which will find the list of queries creating tmp_disk_tables:</p>
<pre>
#pragma D option quiet
dtrace:::BEGIN
{
printf("Tracing... Hit Ctrl-C to end.\n");
}

pid$target::*mysql_parse*:entry
{
self->query = copyinstr(arg1);
}

pid$target::*create_myisam_tmp_table*:return
{
@query[self->query] = count();
}
</pre>
<p>put it into tmpdisktable.d, chmod +x tmpdisktable.d and run it with<br />
./tmpdisktable.d -p `pgrep -x mysqld`</p>
<p>Ctrl+C after 5 seconds whatever and you will see the queries:</p>
<pre>
# ./tmpdisktable.d -p `pgrep -x mysqld`
Tracing... Hit Ctrl-C to end.
^C
</pre>
<p>Queries are stripped by the &#8220;strsize&#8221;, which is can be tweaked:</p>
<pre>#pragma D option strsize=N</pre>
<p>We can increase the &#8220;strsize&#8221; length now and run the script again to get the real queries examples.</p>
<p>Please note: running dtrace for a while can decrease performance, so do not run it for more than couple minutes on production systems. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.arubin.org/blog/2009/10/02/using-dtrace-to-find-queries-creating-disk-temporary-tables/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

