Задавайте вопросы, мы ответим
Вы не зашли.
SELECT *
FROM
`businesses` b
LEFT JOIN `businesses` b2 ON b2.`id` = b.`id_parent`
LEFT JOIN `businesses` b3 ON b3.`id` = b2.`id_parent`
LEFT JOIN `businesses` b4 ON b4.`id` = b3.`id_parent`
WHERE 189 = b.id
OR 189 = b.`id_parent`
OR 189 = b2.`id_parent`
OR 189 = b3.`id_parent`
OR 189 = b4.`id_parent`
LIMIT 2900, 10
EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE b ALL PRIMARY,FK_businesses_parent,id_parent,id 2761
1 SIMPLE b2 eq_ref PRIMARY,id PRIMARY 4 billing.b.id_parent 1
1 SIMPLE b3 eq_ref PRIMARY,id PRIMARY 4 billing.b2.id_parent 1
1 SIMPLE b4 eq_ref PRIMARY,id PRIMARY 4 billing.b3.id_parent 1 Using where
Почему ALL ?
CREATE TABLE `businesses` (
`id` int(10) unsigned NOT NULL auto_increment,
`id_parent` int(10) unsigned NOT NULL,
`name` varchar(1600) NOT NULL,
`path` tinytext,
`document_type` tinyint(4) unsigned NOT NULL default '1',
`document_sort` int(11) unsigned NOT NULL default '0',
`document_gsort` varchar(255) character set utf8 collate utf8_bin NOT NULL,
`document_level` int(11) unsigned NOT NULL default '0',
`document_sub_folders` int(11) unsigned NOT NULL default '0',
`document_sub_documents` int(11) unsigned NOT NULL default '0',
`document_path` varchar(255) character set utf8 collate utf8_bin NOT NULL,
`document_url` varchar(255) NOT NULL,
`document_publish_time` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_businesses_parent` (`id_parent`),
KEY `id_parent` (`id_parent`,`id`),
KEY `id` (`id`,`id_parent`),
CONSTRAINT `FK_businesses_parent` FOREIGN KEY (`id_parent`) REFERENCES `businesses` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Неактивен
А почему нет? Там же OR везде? Как бы Вы хотели "правильно" построить план?
Неактивен
paulus написал:
А почему нет? Там же OR везде? Как бы Вы хотели "правильно" построить план?
Я бы хотел во всех таблицах использовать индексы. Чтобы ни одна полностью не просматривалсь. С OR это исключено?
Неактивен
Ну, Вы подумайте, как написан Ваш запрос.
"Найди мне строчки, в которых или id 189, или у кого, возможно, есть родитель 189, или, возможно,
у родителя есть родитель 189, или, возможно, у родителя есть дедушка 189".
MySQL поступает правильно: он смотрит всех людей на наличие 189, а потом среди них смотрит
генеалогические связи. Вы бы искали по-другому?
Чтобы ускорить запрос, можете Выбрать не *, а id с правильным OR, а потом построить генеалогическое
дерево. Типа
SELECT id FROM businesses WHERE id=189 OR id_parent=189
Результат будет пробивать по индексу, он будет несколько избыточным, но с ним будет легко
делать LEFT JOIN.
Неактивен
Эммм... Поясните плз по использованию индексов.
Есть таблица, в ней есть составной индекс на 3 поля, ищем записи по этим трём полям (только по этим полям), порядок полей такой же, как указано в индексе, в итоге в эксплейне вижу "Using where".
Неактивен
Самое интересное - это поведение оптимизатора в данной ситуации.
В таблице есть два индекса:
key1 (1, 2, 3)
key2 (2, 1, 3)
Сделано это потому, что пока запросы не поправлены и они могут быть с поиском как по 1, 2, 3 полям, так и по 2, 1, 3.
У поля 2 CARDINALITY выше, по этому запрос с поиском по полям 1, 2, 3 использует всё же индекс key2, а не key1
Т.е. получается, что порядок полей в данной ситуации не актуален :\
Неактивен
Порядок полей в WHERE не важен, оптимизатор их упорядочит. Более того, не так уж важна cardinality отдельных частей составного индекса, см. http://sqlinfo.ru/forum/viewtopic.php?id=151#p1520
Важно какие условия накладываются. Если равенство или IN(), то будет использован весь составной индекс. Если есть неравенство, то оно завершает исползование индекса. Если есть неравенство по двум колонкам, то одна из них будет использована уже в WHERE. EXPLAIN показывает key_len - это длина использованной части индекса.
Неактивен