<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Four ways to optimize paginated displays</title>
	<atom:link href="http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/</link>
	<description>Everything about MySQL Performance</description>
	<lastBuildDate>Sat, 21 Nov 2009 05:23:57 -0800</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: trr</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-490270</link>
		<dc:creator>trr</dc:creator>
		<pubDate>Thu, 26 Feb 2009 13:12:52 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-490270</guid>
		<description>@Sam,

Could that difference have been caused by a large part of that query being cached the second time?</description>
		<content:encoded><![CDATA[<p>@Sam,</p>
<p>Could that difference have been caused by a large part of that query being cached the second time?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bill</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-375935</link>
		<dc:creator>Bill</dc:creator>
		<pubDate>Tue, 11 Nov 2008 21:52:59 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-375935</guid>
		<description>I am with Baron on my app. There is no way to maintain count tables if they possibly searching on any combination of 30 different fields. I also tried Chad Walkers method without success. I have many joins when using count() got 107 for total rows.  When multiplying got 423654. Not sure if my query has other optimization problems but that estimate is far from usable.</description>
		<content:encoded><![CDATA[<p>I am with Baron on my app. There is no way to maintain count tables if they possibly searching on any combination of 30 different fields. I also tried Chad Walkers method without success. I have many joins when using count() got 107 for total rows.  When multiplying got 423654. Not sure if my query has other optimization problems but that estimate is far from usable.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sam</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-362752</link>
		<dc:creator>Sam</dc:creator>
		<pubDate>Fri, 17 Oct 2008 18:09:32 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-362752</guid>
		<description>Baron,

I had a slow query that involved pagination, so I investigated after reading your post on the matter. The result of my investigation was very interesting. Basically, I had a query that was taking about 3 seconds to execute. The SELECT portion of the query was specifying which columns to fetch (i.e. SELECT table.col2, table.col2, ... table.col9). When I simply changed this to &quot;SELECT table.*&quot; the query time dropped to 0.01 sec.! So, in the end, it did not appear that the slowness was a result of the pagination at all (the query uses ORDER BY, GROUP BY, WHERE and LIMIT and orders on a non-indexed field.) Using EXPLAIN did not show any different in the query optimization path for the two forms of query either.  MySQL bug?

Sam</description>
		<content:encoded><![CDATA[<p>Baron,</p>
<p>I had a slow query that involved pagination, so I investigated after reading your post on the matter. The result of my investigation was very interesting. Basically, I had a query that was taking about 3 seconds to execute. The SELECT portion of the query was specifying which columns to fetch (i.e. SELECT table.col2, table.col2, &#8230; table.col9). When I simply changed this to &#8220;SELECT table.*&#8221; the query time dropped to 0.01 sec.! So, in the end, it did not appear that the slowness was a result of the pagination at all (the query uses ORDER BY, GROUP BY, WHERE and LIMIT and orders on a non-indexed field.) Using EXPLAIN did not show any different in the query optimization path for the two forms of query either.  MySQL bug?</p>
<p>Sam</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Baron Schwartz</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-361392</link>
		<dc:creator>Baron Schwartz</dc:creator>
		<pubDate>Sun, 12 Oct 2008 17:51:30 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-361392</guid>
		<description>rar, for SOME applications.  It is absolutely not The End for all.  For many apps I work on, that method would a) not work because there are too many permutations of criteria to count and b) if you could do it, it&#039;d load the site much more heavily than not having counter tables.</description>
		<content:encoded><![CDATA[<p>rar, for SOME applications.  It is absolutely not The End for all.  For many apps I work on, that method would a) not work because there are too many permutations of criteria to count and b) if you could do it, it&#8217;d load the site much more heavily than not having counter tables.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: rar</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-360989</link>
		<dc:creator>rar</dc:creator>
		<pubDate>Fri, 10 Oct 2008 00:48:45 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-360989</guid>
		<description>Ditto David. Maintain count tables. The End.</description>
		<content:encoded><![CDATA[<p>Ditto David. Maintain count tables. The End.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Baron Schwartz</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-359383</link>
		<dc:creator>Baron Schwartz</dc:creator>
		<pubDate>Fri, 03 Oct 2008 13:26:30 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-359383</guid>
		<description>David, thanks for sharing your approach.  That looks like a great way to do it.  I think it would be hard to apply to search results (as on a shopping site) where searching is the norm and showing by category is less used, but in this case it looks like a perfect match.  Knowing your data and access patterns lets you do all kinds of good things!</description>
		<content:encoded><![CDATA[<p>David, thanks for sharing your approach.  That looks like a great way to do it.  I think it would be hard to apply to search results (as on a shopping site) where searching is the norm and showing by category is less used, but in this case it looks like a perfect match.  Knowing your data and access patterns lets you do all kinds of good things!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David BL</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-359345</link>
		<dc:creator>David BL</dc:creator>
		<pubDate>Fri, 03 Oct 2008 09:10:25 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-359345</guid>
		<description>I have recently added paging to my website. First attempt used SQL_COUNT_FOUND_ROWS everywhere. This, unfortunately, slowed things down considerably.

My solution that works very well and has good performance and does NOT remove functionality as this article suggests is:

I&#039;ll explain how I do it for the forum:
-----------------------------------------------
1) I have a statistics table that is updated by triggers on inserts:
 statistics_table(serviceid, count, lastinsert):
 +--------+---------+----------------+
 &#124; SERVICE&#124; COUNTER &#124; LASTINSERT     &#124;
 &#124;--------&#124;---------&#124;----------------&#124;
 &#124; forum  &#124; 10020202&#124; 2008-10-03.... &#124;
 &#124; users  &#124;    10002&#124; 2008-09-13.... &#124;

(I use InnoDB so getting count(*) is too slow)

2) Per forum category I added the same statistics per item in the forum-category table. Again, this table is updated with the same trigger that updates the statistics_table

 +---------+---------+----------------+
 &#124; CATEGORY&#124; COUNTER &#124; LASTINSERT     &#124;
 &#124;---------&#124;---------&#124;----------------&#124;
 &#124; GENERAL &#124;    10001&#124; 2008-10-03.... &#124;
 &#124; TOPIC1  &#124;     1002&#124; 2008-09-13.... &#124;
 &#124; TOPIC2  &#124;     4002&#124; 2008-09-13.... &#124;


Then, based on the query&#039;s where-statements I get the total rows available if its an empty where statement or the counter from the forum-category table if filtered on a category. If its anything else, like free text search or filtered on a user etc. then I fall back to the SQL_COUNT_FOUND_ROWS method.
The tables are so small that they are always cached. I wanted to use in-memory engine, but for some reason I got empty results when querying the forum-category table when in memory.

Making paging links is then easy using (total rows)/(rows per page)

David</description>
		<content:encoded><![CDATA[<p>I have recently added paging to my website. First attempt used SQL_COUNT_FOUND_ROWS everywhere. This, unfortunately, slowed things down considerably.</p>
<p>My solution that works very well and has good performance and does NOT remove functionality as this article suggests is:</p>
<p>I&#8217;ll explain how I do it for the forum:<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
1) I have a statistics table that is updated by triggers on inserts:<br />
 statistics_table(serviceid, count, lastinsert):<br />
 +&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
 | SERVICE| COUNTER | LASTINSERT     |<br />
 |&#8212;&#8212;&#8211;|&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;&#8212;-|<br />
 | forum  | 10020202| 2008-10-03&#8230;. |<br />
 | users  |    10002| 2008-09-13&#8230;. |</p>
<p>(I use InnoDB so getting count(*) is too slow)</p>
<p>2) Per forum category I added the same statistics per item in the forum-category table. Again, this table is updated with the same trigger that updates the statistics_table</p>
<p> +&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
 | CATEGORY| COUNTER | LASTINSERT     |<br />
 |&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;&#8212;-|<br />
 | GENERAL |    10001| 2008-10-03&#8230;. |<br />
 | TOPIC1  |     1002| 2008-09-13&#8230;. |<br />
 | TOPIC2  |     4002| 2008-09-13&#8230;. |</p>
<p>Then, based on the query&#8217;s where-statements I get the total rows available if its an empty where statement or the counter from the forum-category table if filtered on a category. If its anything else, like free text search or filtered on a user etc. then I fall back to the SQL_COUNT_FOUND_ROWS method.<br />
The tables are so small that they are always cached. I wanted to use in-memory engine, but for some reason I got empty results when querying the forum-category table when in memory.</p>
<p>Making paging links is then easy using (total rows)/(rows per page)</p>
<p>David</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: chad walker</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-359067</link>
		<dc:creator>chad walker</dc:creator>
		<pubDate>Wed, 01 Oct 2008 14:22:57 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-359067</guid>
		<description>Oh well, it used to formatted nicely... The point is, you can run explain&#039;s just like any other query. To get an estimate on the number of rows, multiple all of the &#039;rows&#039; columns together (if there is more then one table involved).</description>
		<content:encoded><![CDATA[<p>Oh well, it used to formatted nicely&#8230; The point is, you can run explain&#8217;s just like any other query. To get an estimate on the number of rows, multiple all of the &#8216;rows&#8217; columns together (if there is more then one table involved).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: chad walker</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-359065</link>
		<dc:creator>chad walker</dc:creator>
		<pubDate>Wed, 01 Oct 2008 14:20:08 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-359065</guid>
		<description>Doh! *mental note: don&#039;t include php tags*

    mysql_connect( &quot;host&quot;, &quot;user&quot;, &quot;passwd&quot; );
    mysql_select_db( &quot;db&quot; );
    $res = mysql_query( &quot;EXPLAIN SELECT * FROM users&quot; );
    if( $res )
    {
            $estimate = 1;
            while( $row = mysql_fetch_array($res, MYSQL_ASSOC) )
            {
                    $estimate *= $row[&#039;rows&#039;];
            }
            echo &quot;Estimate rows: $estimate.\n&quot;;
    }
    else
    {
            echo &quot;SQL error.\n&quot;;
    }</description>
		<content:encoded><![CDATA[<p>Doh! *mental note: don&#8217;t include php tags*</p>
<p>    mysql_connect( &#8220;host&#8221;, &#8220;user&#8221;, &#8220;passwd&#8221; );<br />
    mysql_select_db( &#8220;db&#8221; );<br />
    $res = mysql_query( &#8220;EXPLAIN SELECT * FROM users&#8221; );<br />
    if( $res )<br />
    {<br />
            $estimate = 1;<br />
            while( $row = mysql_fetch_array($res, MYSQL_ASSOC) )<br />
            {<br />
                    $estimate *= $row['rows'];<br />
            }<br />
            echo &#8220;Estimate rows: $estimate.\n&#8221;;<br />
    }<br />
    else<br />
    {<br />
            echo &#8220;SQL error.\n&#8221;;<br />
    }</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: chad walker</title>
		<link>http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/comment-page-1/#comment-359064</link>
		<dc:creator>chad walker</dc:creator>
		<pubDate>Wed, 01 Oct 2008 14:18:16 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=508#comment-359064</guid>
		<description>Anupam,
The same way you do any other query, eg:
</description>
		<content:encoded><![CDATA[<p>Anupam,<br />
The same way you do any other query, eg:</p>
]]></content:encoded>
	</item>
</channel>
</rss>
