|
Когда делаем постраничный вывод топиков нам нужно знать общее количество записей в таблице.
Это можно сделать двумя способами. Сделать select count(*) from tableName либо вставить SQL_CALC_FOUND_ROWS в запрос и получать количество с помощью FOUND_ROWS(). Какой вариант предпочтительнее? что работает быстрее?
|
|||||||
| комментировать |
|
Для одной 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, никаких заметных потерь/приростов производительности не было заметно.
|
||||||
| Комментировать |
|
Выше уже правильно написали, но от себя хотел бы добавить следующее: чтобы люди не гадали какие у вас таблицы, какие запросы и прочее, вы всегда можете проверить все сами! Набиваете базу контентом до предполагаемой величины и проверяете запросы на время исполнения. Универсальный способ. Работает 100%. Результаты вас просто поразят - они точнее любого ответа профессионала. А секрет прост - это ваша база, ваши таблицы и ваши запросы.
Времени на эксперимент 10-15 минут, что явно меньше, чем задавать вопрос и ждать ответ. PS Это ни в коему случае не критика, это просто еще один способ найти ответ. Допустим я не стал бы давать ответ на настолько общий вопрос - очень много неизвестных.
|
|||||
|
|
Бывает нужно выбирать записи не только в прямом поряде но и обратном. Здесь представлены эксерименты по измерению времени выборок (сек). Время выборки в прямом и обратном порядке в начале, в середине и конце таблицы.
Выбираются 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
|
|||||
| Комментировать |