SQL_CALC_FOUND_ROWS в MySQL
SQL_CALC_FOUND_ROWS в MySQL
Начиная от версии 4.0 в СУБД MySQL появилась достаточно удобная возможность подсчета количества всех подходящих под запрос записей, когда количество записей ограничивается LIMIT’ом. При работе с поиском в БД, а так же при выборках из таблиц с большим количеством записей такой функционал просто необходим.
Синтаксис. В запросе SELECT перед списком столбцов необходимо указать опцию SQL_CALC_FOUND_ROWS. Вот начало описания синтаксиса конструкции SELECT.
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr, … …
Таким образом, выполняя запрос SELECT SQL_CALC_FOUND_ROWS СУБД подсчитает полное число строк, подходящих под условие запроса, и сохранить это число в памяти. Естественно, имеет смысл запрос SELECT SQL_CALC_FOUND_ROWS только при использовании ограничения (LIMIT). Сразу после выполнения запроса на выборку для получения количества записей нужно выполнить еще один SELECT-запрос: SELECT FOUND_ROWS ();. В результате MySQL вернет одну строку с одним полем, в котором и будет храниться число строк.
Пример самих запросов:
> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE number > 100 LIMIT 10;
> SELECT FOUND_ROWS();
Первый запрос вернет (выведет) 10 строк таблицы tbl_name, для которых выполняется условие number > 100. Второй вызов команды SELECT возвратит количество строк, которые возвратила бы первая команда SELECT, если бы она была написана без выражения LIMIT. Хотя при использовании команды SELECT SQL_CALC_FOUND_ROWS, MySQL должен пересчитать все строки в наборе результатов, этот способ все равно быстрее, чем без LIMIT, так как не требуется посылать результат клиенту.
Пример запросов из PHP:
$result = mysql_query(”SELECT SQL_CALC_FOUND_ROWS * FROM table1 LIMIT 0, 10″, $link);
while ($row = mysql_fetch_assoc($result))
{
var_dump($row);
}
$result = mysql_query(”SELECT FOUND_ROWS()”, $link);
$num_rows = mysql_result($result, 0);
echo “$num_rows Rows\n”;
В результате выполнения кода при условии, что $link указывает на открытое соединение с СУБД, PHP выведет 10 строк из таблицы table1 , а затем целочисленное значение количества строк, соответствующих запросу (без учета LIMIT).
В запросах с UNION SQL_CALC_FOUND_ROWS может вести себя двояко из-за того, что LIMIT может появляться в нескольких местах. Счет строк может вестись для индивидуальных SELECT-запросов, или же для всего запроса после объединения.
Цель SQL_CALC_FOUND_ROWS для UNION состоит в том, что он должен вернуть количество строк, которые будут возвращены без глобального LIMIT. Условия применения SQL_CALC_FOUND_ROWS с UNION перечислены ниже:
- Ключевое слово SQL_CALC_FOUND_ROWS должно указываться в первом операторе SELECT.
- Значение FOUND_ROWS() будет точным только при условии применения UNION ALL. Если указано UNION без ALL, происходит исключение дубликатов, и значение FOUND_ROWS() будет лишь приблизительным.
- Если в UNION не присутствует LIMIT, то SQL_CALC_FOUND_ROWS игнорируется и возвращается количество строк во временной таблице, которая создается для выполнения UNION.
SQL_CALC_FOUND_ROWS, SQL_COUNT_FOUND_ROWS, SQL_ FOUND_ROWS

14 июля 2008 в 21:17
А запись типа SELECT COUNT(id_item) AS count [fields...] FROM table1 LIMIT 0, 10 уже не в моде?;)
Да и использовать перечисление полей вместо * намного экономней. Вдруг в будущем вы добавите в эту тублицу поле типа TEXT или BLOB?
П.С.: а вообще спасибо за статью изучал исходники и нашёл страннную констану)) Бегом в яшу) По этому запросу твой сайт первый ;)
25 июля 2008 в 12:12
Ну и при запросе SELECT COUNT(id_item) AS count [fields...] FROM table1 LIMIT 0, 10 получим в count – 10, независимо от числа записей в таблице :)
28 июля 2008 в 10:16
Как по мне – у вас закралась ошибка. mysql_num_rows() вернет количество строк с LIMIT, а не без него. Для возвращения количества строк без лимита, нужно использовать “SELECT FOUND_ROWS()”
28 июля 2008 в 10:28
mente, верно. Странно, что ее не заметили до сих пор.
24 июня 2010 в 07:36
[...] Подробнее об использовании этой конструкции можно прочитать в посте kurtkrut’а и у Валерия Леонтьева. [...]