SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 12.12.2010 22:57:57

taral
Участник
Зарегистрирован: 12.12.2010
Сообщений: 6

Фильтр новостей по нескольким тегам

Здравствуйте. Подскажите как лучше реализовать запрос
Есть таблица новости
---news---
id  name
1   новость_1
2   новость_2
3   новость_3

Есть таблица теги
---tags---
id   name
1   тег_1
2   тег_2

Соотношение таблиц много к многому потому есть промежуточная таблица
---news_tags---
tag_id    news_id
1             1
2             1
1             2
2             3

Нужно выбрать все новости у которых есть определенные теги. Допустим тег_1 и тег_2. Я делаю запрос такой

SELEC news.*, COUNT(news_tags.*) as count FROM news JOIN news_tags ON (news_tags.news_id = news.id) WHERE news_tags.tag_id IN (1,2) GROUP BY news.id HAVING count=2

В данном случае HAVING count=2 потому что тегов 2.
Проблема заключается в том что в news_tags 4 миллиона записей, в tags 250 и в news 236000. И запрос такого вида обрабатывается достаточно медленно. Подскажите решение.

Неактивен

 

#2 12.12.2010 23:11:42

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Фильтр новостей по нескольким тегам

Попробуйте

SELEC news.* FROM news JOIN
(SELECT news_id FROM  news_tags WHERE news_tags.tag_id IN (1,2) GROUP BY news.id HAVING count(*)=2) t
ON t.news_id = news.id;


Покажите план запроса.

Неактивен

 

#3 12.12.2010 23:20:33

taral
Участник
Зарегистрирован: 12.12.2010
Сообщений: 6

Re: Фильтр новостей по нескольким тегам

В каком смысле план запроса?

Неактивен

 

#4 12.12.2010 23:22:31

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Фильтр новостей по нескольким тегам

EXPLAIN SELEC news.* FROM news JOIN
(SELECT news_id FROM  news_tags WHERE news_tags.tag_id IN (1,2) GROUP BY news.id HAVING count(*)=2) t
ON t.news_id = news.id;


http://dev.mysql.com/doc/refman/5.0/en/ … ation.html

Неактивен

 

#5 12.12.2010 23:34:17

taral
Участник
Зарегистрирован: 12.12.2010
Сообщений: 6

Re: Фильтр новостей по нескольким тегам

id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    PRIMARY    <derived2>    ALL    NULL    NULL    NULL    NULL    53902    
1    PRIMARY    properties    eq_ref    PRIMARY    PRIMARY    4    t.property_id    1    
2    DERIVED    property_filters    index    NULL    PRIMARY    8    NULL    2765472    Using where; Using index
результат. таблицы называются немного по другому. я навел не те имена что бы было проще объяснить задачу. news = properties, property_filters = news_tags и filters = tags

Неактивен

 

#6 12.12.2010 23:43:28

taral
Участник
Зарегистрирован: 12.12.2010
Сообщений: 6

Re: Фильтр новостей по нескольким тегам

Когда идет фильтр по 2 тегам запрос обрабатывается еще терпимо. Но когда их выбрано 5-6 то стает совсем туго

Неактивен

 

#7 13.12.2010 00:11:09

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Фильтр новостей по нескольким тегам

Ну разве что сделать GROUP BY news.id HAVING count(*)=2 ORDER BY NULL

А что говорит show create table property_filters;

Неактивен

 

#8 13.12.2010 02:53:08

taral
Участник
Зарегистрирован: 12.12.2010
Сообщений: 6

Re: Фильтр новостей по нескольким тегам

CREATE TABLE IF NOT EXISTS `property_filters` (
  `property_id` int(11) NOT NULL,
  `filter_id` int(11) NOT NULL,
  PRIMARY KEY (`property_id`,`filter_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
А что если id всех тегов через запятую прописать в отдельном поле properties. К примеру так
---properties---
id  properties     filters
1   property_1      1,2
2   property_2      3,5
3   property_3      6,8
И потом делать запрос только в одну таблицу. Можно ли реализовать что то подобное и имеет ли это смысл? Самое важное мне сейчас это производительность. И ради нее я готов менять структуру таблиц и все остальное. Более мощный сервер тоже вариант. Но этот тоже не худший, а лиш 1 такой запрос заставляет его думать 10-15 сек. И я не уверен что ситуация сильно изменится если я буду снимать более дорогой сервер.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson