berkut
Новичок
оптимизация OR в связях таблиц
как оптимизировать связь по ON (t1.=? OR t1. = ??) ? Собственно есть 3 таблицы: шины, шины-машины(связь какой машине какая подходит шина) и синонимы шин(шина указывает на другую шину). нужно выбрать ID машин, к которым подходит определённая марка шины с учётом синонимов.
не проигнорьте плиз, старался структуру упрощенную делал
запрос:
EXplain
Главный вопрос: как избавится от Range checked for each record? Из-за него огромные тормоза - по 6 секунд выполняется на 8000 рядах в car_tyres
-~{}~ 07.05.08 09:16:
т.е. даже using temporary, file sort у меня не так страшны как each record. Всё дело в том, что под условие попадает не так много рядов.
-~{}~ 07.05.08 09:19:
смысл запроса и синонимов в том, что при поиске по '*naKama'(это отдельная шина, но она ещё и является указателем на kama) должны выбраться машины, к которым подходит резина kama.
как оптимизировать связь по ON (t1.=? OR t1. = ??) ? Собственно есть 3 таблицы: шины, шины-машины(связь какой машине какая подходит шина) и синонимы шин(шина указывает на другую шину). нужно выбрать ID машин, к которым подходит определённая марка шины с учётом синонимов.
не проигнорьте плиз, старался структуру упрощенную делал
Код:
CREATE TABLE car_tyres (
car_id mediumint(9) unsigned NOT NULL default '0',
tyre_id mediumint(9) unsigned NOT NULL default '0',
UNIQUE KEY tyre_id (tyre_id,car_id)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
INSERT INTO `car_tyres` (car_id, tyre_id) VALUES
(1,1),
(1,2);
CREATE TABLE tyres (
id mediumint(9) unsigned NOT NULL auto_increment,
name varchar(20) NOT NULL default '',
params varchar(20) NOT NULL default '',
PRIMARY KEY (id),
FULLTEXT KEY name (name)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
INSERT INTO `tyres` (`id`, `name`, `params`) VALUES
(1, 'kama', ''),
(2, 'пирелли', ''),
(3, 'неВыберется', ''),
(4, '*naKama', '');
CREATE TABLE tyre_synonyms (
tyre_id mediumint(9) unsigned NOT NULL default '0',
synonym_of mediumint(9) unsigned NOT NULL default '0',
UNIQUE KEY tyre_id (tyre_id,synonym_of)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
INSERT INTO `tyre_synonyms` (tyre_id, synonym_of) VALUES
(4,1);
Код:
SELECT SQL_NO_CACHE car_tyres.*
FROM tyres
LEFT JOIN tyre_synonyms ON tyres.id = tyre_synonyms.tyre_id
INNER JOIN car_tyres ON (car_tyres.tyre_id = tyres.id
OR car_tyres.tyre_id = tyre_synonyms.synonym_of)
WHERE MATCH(tyres.name) AGAINST ('*naKama kama' IN BOOLEAN MODE)
GROUP BY car_tyres.car_id
Код:
+----+-------------+---------------+----------+---------------+---------+-------
--+---------------+------+------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+----------+---------------+---------+-------
--+---------------+------+------------------------------------------------+
| 1 | SIMPLE | tyres | fulltext | PRIMARY,name | name |0 | | 1 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | tyre_synonyms | ref | tyre_id | tyre_id |3 | test.tyres.id | 1 | Using index |
| 1 | SIMPLE | car_tyres | ALL | tyre_id | NULL | NULL | NULL | 2 | Range checked for each record (index map: 0x1) |
+----+-------------+---------------+----------+---------------+---------+-------
--+---------------+------+------------------------------------------------+
3 rows in set (0.00 sec)
-~{}~ 07.05.08 09:16:
т.е. даже using temporary, file sort у меня не так страшны как each record. Всё дело в том, что под условие попадает не так много рядов.
-~{}~ 07.05.08 09:19:
смысл запроса и синонимов в том, что при поиске по '*naKama'(это отдельная шина, но она ещё и является указателем на kama) должны выбраться машины, к которым подходит резина kama.