<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
				<title>Comments on: MySQL: Pagination - SQL_CALC_FOUND_ROWS vs COUNT()-Query</title>
		<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html</link>
		<description>MySQL: Pagination - SQL_CALC_FOUND_ROWS vs COUNT()-Query Comment Feed</description>
				<language>de</language>
		<pubDate>Thu, 09 Sep 2010 20:16:40 +0000</pubDate>
		<generator>mcw[blog] 'Ruby' Alpha 3</generator>
		<item>
			<title>Comment #1 by: Srini</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment2271</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment2271</guid>
			<author>Srini</author>			
			<pubDate>Tue, 30 Jun 2009 17:10:56 +0000</pubDate>
			<content:encoded><![CDATA[ Cool! Its 100% True! ]]></content:encoded>
		</item>
		<item>
			<title>Comment #2 by: Ronald H.</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment2304</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment2304</guid>
			<author>Ronald H.</author>			
			<pubDate>Thu, 02 Jul 2009 01:30:42 +0000</pubDate>
			<content:encoded><![CDATA[ Thanks buddy. I'll be using this code in the future. I also thought you'd like to know there is a great domain name at Godaddy.com that you may be interested in. It's call PHPDEVELOPING.COM and I think its a good fit for you because your a great PHP programmer. You can contact me at my email address and I'll help you get to it if you want. Again, just thought you'd like to know. ]]></content:encoded>
		</item>
		<item>
			<title>Comment #3 by: Dominik Jungowski</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment2316</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment2316</guid>
			<author>Dominik Jungowski</author>			
			<pubDate>Thu, 02 Jul 2009 09:21:15 +0000</pubDate>
			<content:encoded><![CDATA[ Just keep in mind that it's not always THE solution. When reading from a table that is very frequently updated (more than once a minute), you won't get too much speed benefits, as with each table update the cache query for the respective table runs out.<br />
<br />
Thanks for the address tip, I'll think about it ]]></content:encoded>
		</item>
		<item>
			<title>Comment #4 by: wasimasif</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment2832</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment2832</guid>
			<author>wasimasif</author>			
			<pubDate>Wed, 15 Jul 2009 13:48:20 +0000</pubDate>
			<content:encoded><![CDATA[ In my experience sometimes its good to use SQL_CALC_FOUND_ROWS instead of running separate queries for count. <br />
<br />
If you are running full-text query on table with 2M+ rows then its good idea to use it. When we tried the query with SQL_CALC_FOUND_ROWS, performed better than two separate queries.<br />
<br />
I also agree to prefer SQL_CALC_FOUND_ROWS on frequently updated table. ]]></content:encoded>
		</item>
		<item>
			<title>Comment #5 by: php</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment3060</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment3060</guid>
			<author>php</author>			
			<pubDate>Tue, 21 Jul 2009 14:56:07 +0000</pubDate>
			<content:encoded><![CDATA[ thanks for great post ]]></content:encoded>
		</item>
		<item>
			<title>Comment #6 by: pe3sos</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment5625</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment5625</guid>
			<author>pe3sos</author>			
			<pubDate>Mon, 12 Oct 2009 13:42:19 +0000</pubDate>
			<content:encoded><![CDATA[ Cool very beatiful, thanks a lot!!!!  ]]></content:encoded>
		</item>
		<item>
			<title>Comment #7 by: Vlad</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment7932</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment7932</guid>
			<author>Vlad</author>			
			<pubDate>Mon, 30 Nov 2009 18:36:43 +0000</pubDate>
			<content:encoded><![CDATA[ Бывает нужно выбирать записи не только в прямом поряде но и обратном. Здесь представлены эксерименты по измерению времени выборок (сек). Время выборки в прямом и обратном порядке в начале, в середине и конце таблицы.<br />
<br />
Выбираются 100 строк из таблицы в 15198 строк . Таблица вида:<br />
1;aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;999;999,9;aaaaaaaaaa;aaaaaaaaaaaaa;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;32<br />
Первое и последнее поля - индексы.<br />
<br />
<br />
# Общий вывод<br />
- Как при прямой выборке, так и при обратной, подсчет строк вести с помощью COUNT, а не SQL_CALC_FOUND_ROWS.<br />
- В обратном порядке никогда не извлекать. Правда придется подсчитать строки и обратить массив, но это работает всегда быстрее, чем даже обратная выборка без подсчета.<br />
<br />
<br />
<br />
#1<br />
# Реверс с помощью array_reverse() не влияет на время, то есть лучше извлекать в прямом порядке и обращать массив в PHP<br />
<br />
	В начале<br />
		SELECT * FROM `alifpress_tab_drugs&#8211;` WHERE blockId=86 LIMIT 0, 100<br />
		0,002529 | rev: 0,002408<br />
	В середине<br />
		SELECT * FROM `alifpress_tab_drugs&#8211;` WHERE blockId=86 LIMIT 7000, 100<br />
		0,033052 | rev: 0,033089<br />
	В конце<br />
		SELECT * FROM `alifpress_tab_drugs&#8211;` WHERE blockId=86 LIMIT 15097, 100<br />
		0,068655 | rev: 0,068438<br />
<br />
<br />
<br />
#2<br />
# Последние 100 строк в обратном порядке (ORDER BY и DESC) извлекаются на 21%  дольше, чем подсчет строк (COUNT), извлечение последних 100 строк в прямом порядке и обращение массива! И это было лучшее проявление обратной выборки, то есть выборка в конце таблицы (ORDER BY recId DESC LIMIT 0, 100).  Применять же обратную выборку в середине или начале таблицы вообще не стоит - это время больше в 12 раз, чем при выборке в конце таблицы! <br />
	SELECT COUNT(*) AS count FROM `alifpress_tab_drugs&#8211;`<br />
	SELECT * FROM `alifpress_tab_drugs&#8211;` WHERE blockId=86 LIMIT 15097, 100<br />
	array_reverse()<br />
		0,096872<br />
		0,091073<br />
		0,088885<br />
<br />
<br />
	SELECT * FROM `alifpress_tab_drugs&#8211;` WHERE blockId=86 ORDER BY recId DESC LIMIT 0, 100<br />
		0,112414<br />
		0,111679<br />
		0,109608<br />
<br />
<br />
#3.<br />
# Подсчет с помощью COUNT  и выборка 100 строк в прямом порядке работает 3,5 раз быстрее, чем с помощью SQL_CALC_FOUND_ROWS. <br />
	SELECT COUNT(*) AS count FROM `alifpress_tab_drugs&#8211;`<br />
	SELECT * FROM `alifpress_tab_drugs&#8211;` WHERE blockId=86 LIMIT 0, 100<br />
		0,020637<br />
		0,020737<br />
		0,020941<br />
	SELECT SQL_CALC_FOUND_ROWS * FROM `alifpress_tab_drugs&#8211;` WHERE blockId=86 LIMIT 0, 100<br />
		0,073836<br />
		0,072075<br />
		0,071991<br />
<br />
<br />
#4.<br />
# Для подсчета строк при обратной выборке SQL_CALC_FOUND_ROWS ни в коем случае не использовать.  Этот запрос как бы делает свою работу за одно с выборкой, но лучше подсчитать число строк отдельно с помощью COUNT.<br />
<br />
При обратной выборке на всех диапазонах <br />
	SELECT SQL_CALC_FOUND_ROWS * FROM `alifpress_tab_drugs&#8211;` WHERE blockId=86 ORDER BY recId DESC LIMIT 0, 100<br />
	1,23811<br />
	1,265026<br />
	1,199161<br />
<br />
 ]]></content:encoded>
		</item>
		<item>
			<title>Comment #8 by: Gendalf</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment9058</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment9058</guid>
			<author>Gendalf</author>			
			<pubDate>Fri, 25 Dec 2009 19:04:17 +0000</pubDate>
			<content:encoded><![CDATA[ В моем случае, есть очень много сложнейших запросов с результатами более чем по 1000 страниц по сотне записей на каждой&#8230; и время ожидания должно быть не более 0.1 сек.. вообщем вышел из положения следующей прозрачно оберткой для своего класса в пхп.<br />
<br />
Суть в том, чтобы прозрачно выбирать "селект" запросы с "SQL_CALC_FOUND_ROWS", при первом запросе выбираем список всех таблиц из запроса, фиксируем максимальную дату изменения, и ложим кол-во записей в кеш. Если одна из таблиц меняется, кеш обновляется. Кусочек кода прилагаю. С С первого взгляда сильно много букв и движений, но в результате о долгих запросах изза пересчета всех записей можно забыть.<br />
<br />
private function smart_count_cache() {		<br />
		if(!stripos($this->sql, 'SQL_CALC_FOUND_ROWS') && !$this->smart_cache_init) return;<br />
		<br />
		// Удаляем из запроса операторы Limit и Order<br />
		$sql = preg_replace(array('/Limit\s[0-9\s,]+/si',"/Order By[^\n]+/si"), '', $this->sql);<br />
		// Если кеш не инициализирован, создаем таблицу<br />
		if (!$this->smart_cache_init) <br />
				mysql_query("CREATE TABLE IF NOT EXISTS `@smart_cache` (`query_hash` varchar(64) NOT NULL, `cache_timepoint` int(11) NOT NULL, `query_rows` int(11) DEFAULT 0, PRIMARY KEY (`query_hash`)) ENGINE=HEAP;", $this->DB);				<br />
		else { <br />
			// Если нет, получаем информацию о кол-во строк<br />
			$q = mysql_query("Select FOUND_ROWS() as recount", $this->DB); $r = mysql_fetch_array($q); mysql_free_result($q);	<br />
			// Сохраняем ее в кеше информацию<br />
			mysql_query("Replace `@smart_cache` Set query_hash = '".md5($sql)."', cache_timepoint = UNIX_TIMESTAMP(), query_rows = {$r['recount']};", $this->DB);<br />
			// И возвращаем<br />
			return $r['recount'];		<br />
		}<br />
		<br />
		$this->smart_cache_init = true;<br />
		<br />
		// Выбираем название всех таблиц, которые участвуют в запросе<br />
		if(preg_match_all('/(from\s|join\s)([\w_]+)/si', $sql, $found)) $tables = implode(',',$found[2]);<br />
		<br />
		// Выбираем самую последнюю дату изменения<br />
		$q = mysql_query("show table status Where FIND_IN_SET(name, '{$tables}')>0", $this->DB); $LastUpdate = 1000;			<br />
		while($r = mysql_fetch_array($q)) if(($n = strtotime($r['Update_time'])) > $LastUpdate) $LastUpdate = $n; mysql_free_result($q);<br />
<br />
		// Проверяем есть ли свежая информация в кеше для этого запроса<br />
		$q = mysql_query("Select query_rows From `@smart_cache` Where query_hash = '".md5($sql)."' AND cache_timepoint >= $LastUpdate");<br />
		$r = mysql_fetch_array($q); mysql_free_result($q);<br />
<br />
		if($r) {			<br />
			// Если есть возращаем информацию 			 <br />
			$this->info['count'] = $r['query_rows'];<br />
			$this->sql = str_ireplace('SQL_CALC_FOUND_ROWS', '', $this->sql); <br />
		}		<br />
	} ]]></content:encoded>
		</item>
		<item>
			<title>Comment #9 by: online</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment9407</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment9407</guid>
			<author>online</author>			
			<pubDate>Sun, 03 Jan 2010 22:47:17 +0000</pubDate>
			<content:encoded><![CDATA[ новых творческих начинаний в новом году!<br />
 ]]></content:encoded>
		</item>
		<item>
			<title>Comment #10 by: solarisadmin</title>
			<link>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment10005</link>
			<guid>http://www.phpdevblog.net/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html#comment10005</guid>
			<author>solarisadmin</author>			
			<pubDate>Sat, 16 Jan 2010 09:17:04 +0000</pubDate>
			<content:encoded><![CDATA[ Thanks a lot!!! ]]></content:encoded>
		</item>
		</channel>
</rss>