За последние 24 часа нас посетили 17816 программистов и 1655 роботов. Сейчас ищут 1573 программиста ...

Хранение/подсчет количества строк таблицы MySQL

Тема в разделе "PHP и базы данных", создана пользователем Русланчек, 15 мар 2011.

  1. Русланчек

    Русланчек Активный пользователь

    С нами с:
    18 фев 2009
    Сообщения:
    13
    Симпатии:
    0
    Народ, подскажите плиз, как лучше хранить данные о количестве строк в таблице?

    Ситуация
    Есть несколько таблиц с некими объектами, в каждой из них около 500-600 тысяч строк, со временем эта цифра увеличивается. На тривиальный SELECT `id` FROM `objects` и mysql_num_rows() каждой таблицы уходит порядка 0,2-0,5 секунды, на мой взгляд - расточительство.

    Я подумал, может завести таблицу, в которую писать при обновлении каждой таблицы число ее строк? Как вообще такая проблема решается оптимальнее?
     
  2. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Русланчек
    Какие типы таблиц? MyISAM? InnoDB?
    Юзай
    [sql]SELECT count(*) FROM `table_name`[/sql]
    И господь сказал: возрадуйся!
     
  3. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Ну, например, форум phpbb количество сообщений в каждой теме, количество тем в каждом форуме и т.п. - хранит в б.д., а не пересчитывает при каждом обращении. Это работает быстрее, конечно.
     
  4. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Забыл:
    Заюзай алиасы для простоты обработки.
    Например:

    [sql]SELECT count(*) AS `records` FROM `table_name`[/sql]
    и РНР соответственно:
    Код (Text):
    1. $row->records
     
  5. Русланчек

    Русланчек Активный пользователь

    С нами с:
    18 фев 2009
    Сообщения:
    13
    Симпатии:
    0
    А count() точно не будет отжирать полсекунды на таблицах-милионниках?
     
  6. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    будет.
     
  7. Русланчек

    Русланчек Активный пользователь

    С нами с:
    18 фев 2009
    Сообщения:
    13
    Симпатии:
    0
    MyISAM
     
  8. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Да хоть миллиардниках.
    Есть понятие индексов, есть понятие первичных ключей.
    Эта информация хранится отдельно от таблицы с записями, разработчики MySQL конструкцию вызов функции count(*) сделали конструкцией языка по сути, оптимизировав её для быстрой выборки количества записей.

    Сравни count(*) с count(id) и убедишься, насколько первый обгоняет.
     
  9. Русланчек

    Русланчек Активный пользователь

    С нами с:
    18 фев 2009
    Сообщения:
    13
    Симпатии:
    0
    Круто! Спасибо!
     
  10. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Структура таблицы:
    [sql]CREATE TABLE `codes` (
    `code_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
    `code` VARCHAR(12) NOT NULL DEFAULT '',
    `code_used` DATETIME DEFAULT NULL,
    PRIMARY KEY(`code_id`),
    KEY(`code`)
    ) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;[/sql]
    В таблице 4 000 002 записи
    На сервере, конечно быстрее, но всё равно не мгновенно, а на локалхосте - вообще жесть:
    [sql]SELECT COUNT(*) FROM `codes`;[/sql]
    4000002
    1 row in set (1 min 16.55 sec)
    [sql]SELECT COUNT(*) FROM `codes`;[/sql]
    4000002
    1 row in set (1 min 15.33 sec)
    [sql]SELECT COUNT(*) FROM `codes` WHERE `code_id` < 99999999;[/sql]
    4000002
    1 row in set (9.83 sec) - любопытно, почему?
    [sql]SELECT COUNT(`code_id`) FROM `codes`;[/sql]
    4000002
    1 row in set (1 min 16.13 sec)
     
  11. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Да, движок InnoDB...
     
  12. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Может потому что я не просто так про тип таблицы спросил, а?
     
  13. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Может, но всё равно остаётся любопытно, почему так :)
     
  14. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Потому что так должно быть.
     
  15. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Да я и не говорю, что такого не должно быть :) Мне просто любопытно, почему с условием, под которое попадают все записи пересчёт строк выполняется в несколько раз быстрее, чем без условия
     
  16. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    sobachnik
    Потому что инфа о кколичестве строк в майсам хранится отдельно, а если есть условие - выполняется проход по строкам.
    В ИнноДб все не так)
     
  17. Shumomer

    Shumomer Активный пользователь

    С нами с:
    12 мар 2011
    Сообщения:
    194
    Симпатии:
    1
    Адрес:
    из вашего вображения
    Индекс включился