MySQL Количество записей в таблице count vs SQL_CALC_FOUND_ROWS

*
1
*
✩
Когда делаем постраничный вывод топиков нам нужно знать общее количество записей в таблице.
Это можно сделать двумя способами.

Сделать
select count(*) from tableName

либо вставить SQL_CALC_FOUND_ROWS в запрос и получать количество с помощью FOUND_ROWS().

Какой вариант предпочтительнее? что работает быстрее?
mysql sql
11 месяцев 25 дней назад
iam
[789]
#ссылка не по теме? tweet сохранить
комментировать



*
4
*
Для одной Myisam таблицы select count(*) from tableName - очень быстрый, и, по-видимому, он будет чуть быстрее чем FOUND_ROWS()(думаю тут больше зависит от реализации оптимизатора запросов).
Если же накладываются какие-то условия, присоединяются другие таблицы, то в сумме
SELECT COUNT(*)
SELECT * LIMIT

vs.
SELECT SQL_CALC_FOUND_ROWS *
FOUND_ROWS()

дадут одно и то же.
Мне лично больше нравится COUNT (более универсальный, и 100% не бажный - в старых версиях MYSQL FOUND_ROWS не всегда правильно работал), но пользовался и SQL_CALC_FOUND_ROWS, никаких заметных потерь/приростов производительности не было заметно.
#ссылка не по теме?
11 месяцев 25 дней назад
a1ex07
[1345]
Комментировать
*
3
*
Выше уже правильно написали, но от себя хотел бы добавить следующее: чтобы люди не гадали какие у вас таблицы, какие запросы и прочее, вы всегда можете проверить все сами! Набиваете базу контентом до предполагаемой величины и проверяете запросы на время исполнения. Универсальный способ. Работает 100%. Результаты вас просто поразят - они точнее любого ответа профессионала. А секрет прост - это ваша база, ваши таблицы и ваши запросы.

Времени на эксперимент 10-15 минут, что явно меньше, чем задавать вопрос и ждать ответ.


PS Это ни в коему случае не критика, это просто еще один способ найти ответ. Допустим я не стал бы давать ответ на настолько общий вопрос - очень много неизвестных.
#ссылка не по теме?
11 месяцев 25 дней назад
Koshak
[689]
безусловно я не делаю выводы только на ответах других, но как часто бывает есть какая нибудь мелочь о которой никто не знает, и ее кто-то подскажет и она будет переломной в выборе решения. Спасибо за ответы. – iam 11 месяцев 25 дней назад
Комментировать
*
1
*
Бывает нужно выбирать записи не только в прямом поряде но и обратном. Здесь представлены эксерименты по измерению времени выборок (сек). Время выборки в прямом и обратном порядке в начале, в середине и конце таблицы.

Выбираются 100 строк из таблицы в 15198 строк . Таблица вида:
1;aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;999;999,9;aaaaaaaaaa;aaaaaaaaaaaaa;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;32
Первое и последнее поля - индексы.


# Общий вывод
- Как при прямой выборке, так и при обратной, подсчет строк вести с помощью COUNT, а не SQL_CALC_FOUND_ROWS.
- В обратном порядке никогда не извлекать. Правда придется подсчитать строки и обратить массив, но это работает всегда быстрее, чем даже обратная выборка без подсчета.



#1
# Реверс с помощью array_reverse() не влияет на время, то есть лучше извлекать в прямом порядке и обращать массив в PHP

В начале
SELECT * FROM `alifpress_tab_drugs--` WHERE blockId=86 LIMIT 0, 100
0,002529 | rev: 0,002408
В середине
SELECT * FROM `alifpress_tab_drugs--` WHERE blockId=86 LIMIT 7000, 100
0,033052 | rev: 0,033089
В конце
SELECT * FROM `alifpress_tab_drugs--` WHERE blockId=86 LIMIT 15097, 100
0,068655 | rev: 0,068438



#2
# Последние 100 строк в обратном порядке (ORDER BY и DESC) извлекаются на 21% дольше, чем подсчет строк (COUNT), извлечение последних 100 строк в прямом порядке и обращение массива! И это было лучшее проявление обратной выборки, то есть выборка в конце таблицы (ORDER BY recId DESC LIMIT 0, 100). Применять же обратную выборку в середине или начале таблицы вообще не стоит - это время больше в 12 раз, чем при выборке в конце таблицы!
SELECT COUNT(*) AS count FROM `alifpress_tab_drugs--`
SELECT * FROM `alifpress_tab_drugs--` WHERE blockId=86 LIMIT 15097, 100
array_reverse()
0,096872
0,091073
0,088885


SELECT * FROM `alifpress_tab_drugs--` WHERE blockId=86 ORDER BY recId DESC LIMIT 0, 100
0,112414
0,111679
0,109608


#3.
# Подсчет с помощью COUNT и выборка 100 строк в прямом порядке работает 3,5 раз быстрее, чем с помощью SQL_CALC_FOUND_ROWS.
SELECT COUNT(*) AS count FROM `alifpress_tab_drugs--`
SELECT * FROM `alifpress_tab_drugs--` WHERE blockId=86 LIMIT 0, 100
0,020637
0,020737
0,020941
SELECT SQL_CALC_FOUND_ROWS * FROM `alifpress_tab_drugs--` WHERE blockId=86 LIMIT 0, 100
0,073836
0,072075
0,071991


#4.
# Для подсчета строк при обратной выборке SQL_CALC_FOUND_ROWS ни в коем случае не использовать. Этот запрос как бы делает свою работу за одно с выборкой, но лучше подсчитать число строк отдельно с помощью COUNT.

При обратной выборке на всех диапазонах
SELECT SQL_CALC_FOUND_ROWS * FROM `alifpress_tab_drugs--` WHERE blockId=86 ORDER BY recId DESC LIMIT 0, 100
1,23811
1,265026
1,199161

#ссылка не по теме?
9 месяцев 27 дней назад
Комментировать

Ваш Ответ:


Ваш OpenID


Получить OpenID

Что такое OpenID?
или

Логин

Email

Пароль


Будет создана учетная запись и на email выслано письмо подтверждения.


новые ответы

Первый раз на сайте?

askdev.ru — это социальный сайт вопросов и ответов для IT-специалистов: программистов, веб-дизайнеров, системных администраторов.
о сайте » регистрация »

Показан

995 раз

Задан

11 месяцев 25 дней назад

Теги
mysql x 123
sql x 68
X

Пожалуйста, войдите:


Имя:
Пароль:
регистрация
Или используйте OpenID