У меня есть большая таблица (60+) миллионов записей.
Я использую PHP-скрипт для навигации по этой таблице.
PHP-скрипт (с разбивкой на страницы) загружается очень быстро, потому что:
Механизм таблицы – InnoDB, поэтому SELECT COUNT()
очень медленный, а mysql_num_rows()
не является опцией, поэтому я сохраняю общее количество строк (число, которое я использую для создания разбивки на страницы) в отдельной таблице (я обновляю эту запись total_rows=total_rows-1
и total_rows=total_rows1+1
во время DELETE
и INSERT
).
Но вопрос в том, что делать с разбиением на страницы на результаты поиска?
Сейчас я делаю это с двумя шагами:
1.
$condition = " fname='rinchik' "; $result = "SELECT * FROM my_large_table WHERE" . $condition;
Здесь я получил все результаты поиска из DataBase.
2. Теперь мне нужно посчитать эти результаты, чтобы создать разбивку на страницы. Я делаю это:
$condition; <- we already have this from the step 1 $result_count = "SELECT COUNT(id) FROM my_large_table WHERE" . $condition;
И это довольно медленно.
Было бы лучше, если я сделаю это так (всего на один шаг) ?:
$condition = " fname='rinchik' "; $result = "SELECT * FROM my_large_table WHERE" . $condition; $result_count = mysql_num_rows($result);
Используйте COUNT
, внутренне сервер будет обрабатывать запрос по-разному.
При выполнении COUNT
сервер будет выделять память только для хранения результата подсчета.
При использовании mysql_num_rows
сервер обрабатывает весь набор результатов, выделяет память для всех этих результатов и помещает сервер в режим выборки, который включает в себя множество разных деталей, таких как блокировка.
Подумайте об этом, как о следующих псевдоценариях:
SELECT COUNT(*)
Эй, Боб, сколько людей в классе?
mysql_num_rows
Эй, Боб, отправь всех людей из классной комнаты мне, … Я посчитаю их, чтобы самому собрать людей
Таким образом, при использовании mysql_num_rows
вы переносите все записи клиенту, а клиенту приходится вычислять сам счет.
Используйте COUNT (id). Он возвращает только счетчик, с mysql_num_rows($result);
php извлекает ВСЕ данные из mysql и подсчитывает количество найденных результатов.
И, наконец, не используйте функции mysql_ *.
Предлагаемые альтернативы
Использование этого расширения не рекомендуется. Вместо этого следует использовать расширение MySQLi или PDO_MySQL. См. Также MySQL: выбирая руководство по API и связанные с ним FAQ для получения дополнительной информации. Альтернативы этой функции включают:
mysqli_stmt_num_rows () PDOStatement :: rowCount ()
Протестировано в двигателе inoDB
и mysql 5.5.
id
имеет индекс, и я думаю, что это очень быстро
$q = "SELECT count(`id`) FROM table where 1"; $rows = mysql_query($q); $count = mysql_fetch_array($rows); echo $count[0];
если вы хотите больше, вам нужно использовать один индекс только по id
или тому, что вы хотите выбрать.
Кэширование – еще одно решение, и вы можете выбрать один набор записей за несколько миллисекунд !