оптимизация JOIN для системы тегов

Vika

Новичок
оптимизация JOIN для системы тегов

Нужно реализовать систеиу тегов.
Есть 2 таблицы :
1. Таблица связей тегов и новостей

CREATE TABLE `rdm_tags2news` (
`tn_id_news` int(10) NOT NULL default '0',
`tn_id_tag` int(10) NOT NULL default '0',
PRIMARY KEY (`tn_id_news`,`tn_id_tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2. Таблица новостей

CREATE TABLE `rdm_news` (
`nw_id` int(10) unsigned NOT NULL auto_increment,
`nw_country_ref` int(10) default NULL,
`nw_status` tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (`nw_id`),
KEY `nw_country_ref` (`nw_country_ref`,`nw_status`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT;

nw_status - статус новости: активная или заблокированная
nw_country_ref - страна: россия, украина

Нужно показать все активные новости одной страны с выбранными тегами (например массив тегов).

запрос с LEFT JOIN работает очень долго и вешает систему.

SELECT n.* FROM rdm_news as n
LEFT JOIN rdm_tags2news as t2n
ON n.nw_id = t2n.tn_id_news
WHERE (tn_id_tag = 806||tn_id_tag = 878) && (n.nw_country_ref = 1) && (n.nw_status = 2) GROUP BY n.nw_id
ORDER BY n.nw_id
DESC LIMIT 30

Можно придумать замену LEFT JOIN?
 

Vika

Новичок
--+------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref
| rows | Extra |
+----+-------------+-------+--------+------------------------+---------+---------+------------------
--+------+-----------------------------------------------------------+
| 1 | SIMPLE | t2n | index | PRIMARY | PRIMARY | 8 | NULL
| 231 | Using where; Using index; Using temporary; Using filesort |
| 1 | SIMPLE | n | eq_ref | PRIMARY,nw_country_ref | PRIMARY | 4 | rdm.t2n.tn_id_new
s | 1 | Using where |
+----+-------------+-------+--------+------------------------+---------+---------+------------------
 

KaYSer

Новичок
а почему двойной первичный ключ? а отчего таблицы делать разных типов?

упс... уже столько ответов успело набежать)
 

Vika

Новичок
это один двойной ключ, чтоб не было повторов

таблицы разных типов это из-за невнимательности,
это я взяла из phpMyAdmin, а на сервере MyISAM

group by, чтоб показал каждую новостьс этими тегами только один раз, а не столько, сколько в ней тегов
 

Vika

Новичок
4.1.22

-~{}~ 22.05.07 13:54:

у меня есть идея в таблицу соответствий тегов и новостей rdm_tags2news добавить поля статус новости и страна новости, и тогда делать выборку только по этой таблице, а потом уже читать саму новость по найденому id новости.

Только придется каждый раз при изменении статуса новости, перезаписывать его в таблице соответствий.
 

alpine

Новичок
Я бы сделал
OPTIMIZE TABLE news, tags
и написал примерно такой запрос
[sql]
SELECT
*
FROM news as n
WHERE n.status=1 AND n.country=1
AND EXISTS(SELECT * FROM tags as t WHERE t.id IN(1,2,3) AND n.id=t.news_id )
ORDER BY n.date DESC
[/sql]
 

MajestiC

Пых
Vika
Это не громадные таблицы.

А вообще вы свой вариант оптимизации пробовали? Вполне приличный вариант, если вам настолько важна скорость. Конечно немного некрасиво, засчет денормализации, но зато эффективно, я сам использую подобный трюк с тэгами.
 

chira

Новичок
Vika

Похоже LEFT JOIN здесь не нужен.
Если список tn_id_tag не большой, можно попробовать UNION вместо OR
 
Сверху