Как оптимизировать "тяжелый" запрос?

Bermuda

Новичок
во-первых, тут напрашивается нормализация - заменяем имя модуля на его id (создавая таблицу всех модулей), заменяем тег на его id (аналогично).
но, вообще-то, мне кажется, что четыре байта заведомо меньше, чем 255
Попробовал. Как я и ожидал, прироста производительности не наблюдается. Оно ж индексы использует.
 

hermit_refined

Отшельник
т.е. только с одной таблицей тоже 4 часа?
приведите структуру, запрос и explain.
 

algo

To the stars!
Сделай Stored Procedure или UDF, которая будет делать такой запрос более оптимально, чем это осуществляет mysql.
 

Bermuda

Новичок
hermit_refined
Нет, с одной таблицей не пробовал
Пробовал это
нормализация - заменяем имя модуля на его id (создавая таблицу всех модулей)
В предположении, что мускул может быть оптимизирован для чисел лучше.
 

hermit_refined

Отшельник
дык, это имело смысл прежде всего для последующего безболезненного объединения в одну таблицу.
но то, что нет вовсе "прироста производительности" - не верю; ибо меньший объем данных для filesort, да и для индексов - тоже.
 

algo

To the stars!
Да, еще вариант - сделать триггер на изменение этих таблиц, который будет обновлять нужный агрегат.

Может, это - то, что тебе надо..
 

Bermuda

Новичок
но то, что нет вовсе "прироста производительности" - не верю
Последние пробы делал на намного меньшей выборке. 0,7-0,8 секунд при неоднократном повторении запроса.
ибо меньший объем данных для filesort
Если сделать ORDER BY NULL то filesort оно не делает.
сделать триггер на изменение этих таблиц
Как вариант, но хочется кроссплатформенно, хотя речь идет о мускуле.

-~{}~ 26.03.07 12:01:

Да, я еще уменшил разрем поля modulo до 15 в таблице tags_cont, и idtag до 15 в таблице tags_tags. Прирост производительности если и есть, то находится в приделах погрешности измерений.
 
Не совсем понятно, почему тег ссылается на таблицу связей, а не наоборот. Почему бы не сделать так:
Таблица tag:
tag_id
tag_title

Таблица tagrelation:
tagrelation_master_id
tagrelation_master_type
tagrelation_tag_id

где tagrelation_master_type - имя модуля, tagrelation_master_id - id сущности.
 

Bermuda

Новичок
2NetFly
Хм... попробую объяснить задачу.
Есть некая запись. У записи есть инеднтификатор, запись находится в каком-либо из модулей. У записи могут быть ключевые слова -- тэги.
Требуется (в порядке убывания приоритета)
1. Строить облако тэгов
2. Посчитать количество записей с данным тэгом.
3. Получить список всех записей с указанным тэгом.
4. При запросе записи иметь возможность получить все тэги ей присвоенные.
5. Добалять новые тэги для существующих записей.
 
Я знаю что такое теги, приведенную выше структуру я выдрал из пакета, которым мы пользуемся сами. Если учесть, что ты тоже используешь одну систему тегов в пределах всего проекта (составной ключ: имя модуля + id сущности), то задачи и требования у нас практически идентичные. Со структурой, которую я описал выше, все указанные тобой задачи решаются достаточно просто и очевидно.

Например, теги присвоенные записи, с их весом можно получить следующим запросом:
PHP:
select tag_title, count(*) as tag_weight 
from tag, tagrelation 
where tagrelation_master_type = 'news' 
AND tagrelation_master_id = 1 
AND tag_id = tagrelation_tag_id 
group by tag_id
Облако тегов:
PHP:
select tag_title, count(*) as tag_weight 
from tag, tagrelation 
where tag_id = tagrelation_tag_id 
group by tag_id 
order by tag_weight desc 
limit 100
Если интересно, могу дать информацию по скорости выполнения запросов при 100k тегов и 400k связей.
 
Кстати, я не до конца уловил идею твоей системе. Насколько я понял, когда пользователь прописывает тег для сущности, он (тег) у тебя добавляется в таблицу независимо от того, был уже такой до этого, или нет. Если так, то это, IMHO, и есть одна из проблем.

select count(*) from tagrelation;
+----------+
| count(*) |
+----------+
| 274125 |
+----------+
1 row in set (0.00 sec)


select count(*) from tag;
+----------+
| count(*) |
+----------+
| 49773 |
+----------+
1 row in set (0.01 sec)


select tag_title, count(*) as tag_weight from tag, tagrelation where tag_id = tagrelation_tag_id group by tag_id order by tag_weight desc limit 100;
...
100 rows in set (3.67 sec)
 

Bermuda

Новичок
2NetFly
Да, совсем забыл, еще требуется фильтровать облако по имени модуля.
 
А в чем сложность?

select tag_title, count(*) as tag_weight from tag, tagrelation where tag_id = tagrelation_tag_id AND tagrelation_master_type = 'news' group by tag_id order by tag_weight desc limit 100;
 
Сверху