За последние 24 часа нас посетил 60651 программист и 1743 робота. Сейчас ищут 909 программистов ...

MySQL count'ы и limit'ы

Тема в разделе "MySQL", создана пользователем maxmuha, 23 окт 2015.

  1. maxmuha

    maxmuha Новичок

    С нами с:
    11 янв 2015
    Сообщения:
    107
    Симпатии:
    0
    Адрес:
    Мурманск
    В наличии
    Таблица с колонками: id, type, category, link, ......
    Primary id, index type, index category, full text link.
    В таблице 270000 записей (пока).
    Для пагинации используется запрос:
    SELECT COUNT(*) FROM table WHERE type = A and category = B;
    По результату этого запроса готовится запрос с LIMIT'ом.
    В результате получается 'затратный' COUNT + не менее затратная выборка LIMIT'а (с большими параметрами) ≈ 2 сек.
    Интересуют возможные способы ускорить этот процесс.
    Изменить таблицу? Добавить таблицу? Вообще нужно что-то менять?
    Вообщем ищу подсказки.

    Добавлено спустя 35 секунд:
    MySQL MyISAM
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    страница 1: WHERE id > 20000 LIMIT 100
    страница 2: WHERE id > (последний id из страницы 1) LIMIT 100

    2 сек много, по идее из 1.000.000 должно за доли секунды выводить
     
  3. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    type = A and category = B

    cделай индекс по двум этим полям в таком порядке, в котором запрашиваешь.
     
  4. maxmuha

    maxmuha Новичок

    С нами с:
    11 янв 2015
    Сообщения:
    107
    Симпатии:
    0
    Адрес:
    Мурманск
    Вот я и переживаю что много, точнее долго.
    За доли секунды count(*) без условия даст ответ.
    id ни к сортировке ни к условиям не применяется, id применяется для соединения с другими таблицами...
    Вся сортировка (идея) для быстрой навигации по категориям, тематикам, тэгам, а в перспективе еще и поиску...
    count(*) WHERE type = A AND category = B будет перебирать все записи по условию и плюсовать каждую запись...

    Добавлено спустя 7 минут 27 секунд:
    надо попробовать на другом аппарате протестировать, может в этом дело...

    Добавлено спустя 2 минуты 27 секунд:
    Если только по type = A 0.871s 270000 rows
    По category = B 0.672s 54371 rows
     
  5. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
     
  6. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    maxmuha индекс стоит как тебе выше советовали?
    Ничего что id не используеться, можешь протестировать
     
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Имеет смысл кешировать результат COUNT() если он не часто меняется. Правда это не ускорит выборку по LIMIT m,nпри больших m она тормозная. Эту штуку можно оптимизировать таким приёмом:
    - в запросе с LIMIT выбирать только id "главной" таблицы, что позволит выкинуть из выборки всё лишнее, особенно джойны. набор айдишников для всей страницы собрать в массив
    - вызвать второй запрос без лимита, но со всеми полями и джойнами, условие по WHERE id IN(список_айдишников)
     
  8. maxmuha

    maxmuha Новичок

    С нами с:
    11 янв 2015
    Сообщения:
    107
    Симпатии:
    0
    Адрес:
    Мурманск
    Проблема в localhost (не торопливый).
    На VDS'ке приемлимо работает.

    Database changed
    mysql> select count(*) from files
    -> WHERE type = 'straight';
    +----------+
    | count(*) |
    +----------+
    | 273948 |
    +----------+
    1 row in set (0.14 sec)

    mysql> select count(*) from files
    -> where type = 'straight'
    -> and category = 'hardcore';
    +----------+
    | count(*) |
    +----------+
    | 54673 |
    +----------+
    1 row in set (0.11 sec)

    mysql> select count(*) from files where type = 'straight' and category = 'hardcore';
    +----------+
    | count(*) |
    +----------+
    | 54673 |
    +----------+
    1 row in set (0.09 sec)

    mysql> select count(*) from files where type = 'straight' and category = 'hardcore';
    +----------+
    | count(*) |
    +----------+
    | 54673 |
    +----------+
    1 row in set (0.10 sec)

    Добавлено спустя 53 секунды:
    Благодарю за подсказки.
    Все попробую.

    Добавлено спустя 1 минуту 52 секунды:
    Благодарю за подсказки.
    Все попробую.
     
  9. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Странно, а чем была проблема?