2012-02-18 2 views
0

Мой вопрос о выборе наилучшего метода для выполнения задания. я представлю цель и различные решения.mysql views performance vs extra column

У меня есть список предметов и список категорий. каждый из них может принадлежать нескольким категориям.

items   (id, name, ...other fields...) 
categories  (id, name, ......) 
category_items (category_id, item_id) 

список предметов очень большой и обновляется каждые 10 минут (с использованием cron). список категорий фиксирован.

на моей странице, я показываю большой список предметов, и у меня есть фильтры категорий. вся фильтрация выполняется на javascript на стороне клиента. Причина в том, что доступные в настоящее время элементы ограничены + 1000, поэтому все данные (элементы + категории) будут загружаться вместе.

Эта страница собирается быть просмотрена много раз, поэтому производительность является проблемой здесь. У меня есть несколько идей, которые приведут к хорошей производительности. во всех из них будет отправлен полный список категорий. пункты, однако ...

  1. запуск одного выбора с использованием join и group_concat. что-то вроде этого:.

    ВЫБРАТЬ I *, GROUP_CONCAT (. CI category_id Сепаратор "") КАК category_list ИЗ items КАК я LEFT JOIN category_items AS КЕ на (CI item_id = я id.). ГДЕ ... ГРУППА BY i. id ORDER BY ...

  2. создания представления с выше

  3. хранения результата GROUP_CONCAT в качестве дополнительного столбца. это будет обновляться каждые несколько минут в режиме cron.

индексация выполнена правильно, поэтому все методы будут работать относительно быстро. join - тяжелая операция, поэтому мой вопрос о (2), (3):

- это обновление, обновленное только на каждом CRUD, или оно рассчитано на каждый выбор? если он обновляется только на CRUD, он должен быть примерно таким же, как и хранение столбца.

Помните, что таблица элементов будет расти, и будут выбраны только последние строки.

+0

Это зависит - вам придется проверять себя, со временем по мере увеличения количества строк. –

ответ

1

Решение 4. Введите таблицу типов MEMORY, которая будет обновлена ​​с результатами вашего запроса из решения 1, с помощью того же скрипта cron, который обновляет таблицу items.

Кроме этого: 1. и 2. эквивалентны. Представления MySQL не реализованы, поэтому запрос к представлению фактически запустит SELECT из точки 1.

+0

из того, что я понимаю, таблица памяти будет такой же, как решение 3 (дополнительный столбец), когда дело доходит до производительности, будет сохранено только пространство, так как group_concat будет храниться только для последних (выбранных) результатов. это верно? – galchen

+0

'MEMORY' будет быстрее, потому что он всегда хранится в ОЗУ (при условии, что на сервере этого достаточно), в то время как ваши обычные таблицы' MyISAM'/'InnoDB' хранятся на диске. Он также может использовать индексы типа 'HASH', которые очень быстрые для' = 'comaprisons (но не так для' LIKE') – Mchl

1

Создание представления просто сохраняет запрос, (2) все равно будет выполнять запрос и соединение. (3), конечно, сэкономит время за счет пространства.

ответа, поэтому вопрос: Есть ли у вас и вашего приложения времени значения или пространство?

Кроме того, вместо использования cron для обновления поля кеша (ваш GROUP_CONCAT) вы можете использовать триггер в таблице category_items;

+0

- это относительно небольшое пространство (особенно, поскольку я сохраняю только идентификаторы). – galchen