Если это ваш первый визит, рекомендуем почитать справку по форуму. Для размещения своих сообщений необходимо зарегистрироваться. Для просмотра сообщений выберите раздел. |
Иерархический запрос в MySQL |
|
Опции темы |
23.09.2014, 15:36 | #1 |
Форумец
Сообщений: 6,684
Регистрация: 26.04.2006
Возраст: 44
Не в сети |
Иерархический запрос в MySQL
Советик нужен небольшой. веб-программирование я подзабросил этак лет 7 назад, многое подзабыл...
А тут потребовалось написать небольшой каталог на MySQL. Дерево организовано просто - есть таблица catalog с полями id, parent_id и caption. Что для чего, думаю объяснять не нужно. Длина ветвей различна, но не больше 5-ти. Конченый (бездетный) элемент каталога связан с записями другой структуры в другой таблице (то есть в этой таблице записи имеют parent_id, равный id одного из "бездетных" элементов каталога) Пару дней я вспоминал php и mysql, написал скриптик, вроде все хорошо, но вот каприз меня взял - хочу после названия элемента каталога писать сколько у него всего потомков, и делать случайную выборку из потомков, принадлежащих какому-то определенному родителю. На каком-то форуме написали, что для решения такой задачи нужно использовать nested set, кто-то привел запрос, который не работает, а связаться с автором совета невозможно. В общем, пока я ждал ответов на свои вопросы и тихо окуевал с nested set (сложно после долгого перерыва в такую жуть вникнуть), чисто из нетерпения и покалывания шила в одном месте, я набросал скрипт, который рекурсивно сканирует каталог, получает список id конечных элементов нужной ветви, а уже из этого списка клеит запрос для SQL в другую таблицу. Работает правильно, надежно и без глюков. Но меня кое что смущает. В каталоге несколько сотен элементов, задача максимум - полное сканирование от корня до конечных ветвей, при вложенности, равной 5-ти, повлекло за собой 400 запросов. Сколько времени - я не мерял, но субъективно - мгновенно, несоизмеримо со временем загрузки страницы. Далее, получив список из 400 с чем-то конечных элементов каталога скрипт сварганил такой запрос: SELECT * FROM table2 WHERE parent_id IN ('1','2','3',.......'450') Забил table2 мусором из 1500 записей и кинул вышеуказанный запрос. Его выполнение заняло 0.0042 сек. В конечном проекте количество каталогов вряд ли превысит 500, а вот элементов будет около 100 000. То есть при наихудшем раскладе 0.42 сек на полный анализ. У меня вопрос следующий - быстродействие то вроде бы удовлетворительное, но по сути, это же изврат...Хостер на меня не обидится? Вы бы стали оставлять так как есть? |
23.09.2014, 20:12 | #2 | ||
highly mean
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35
Не в сети |
Цитата:
Цитата:
Э… выделенный сервер? (Можно не отвечать.) Postgres наверно бы взял… Последний раз редактировалось silly; 23.09.2014 в 20:37. |
||
23.09.2014, 20:42 | #3 | ||
Форумец
Сообщений: 6,684
Регистрация: 26.04.2006
Возраст: 44
Не в сети |
silly,
Цитата:
Я к чему это написал - MySQL при запросе будет анализировать каждую из 100 тыс записей на предмет соответствия parent_id каждой записи одному из 400 идентификаторов. 1500 записей анализщируется за 0.0042 сек. Цитата:
В смысл Nested Set въехал. По сути это та же рекурсия, мой скрипт проходит по дереву каталога тот же путь, что и leftkey и rightkey. Только у моего скрипта это как-то само получается, а тут все разжевывать надо. Пытаюсь понять, насколько MySQL будет быстрее с этим справляться. |
||
23.09.2014, 20:48 | #4 |
Форумец
Сообщений: 6,684
Регистрация: 26.04.2006
Возраст: 44
Не в сети |
Хм... а ведь в Nested Sets это будет даже проще и точно быстрее. Нужно просто выбрать записи, где разница между leftkey и rightkey не больше единицы - это и будут концевые, "бездетные" узлы.
Но этой процедурой мы лишь избавляем MySQL от 400 запросов. Но еще нужно выбрать в таблице №2 все элементы, принадлежащие одному из 400 идентификаторов, полученных в предыдущем запросе. |
23.09.2014, 20:57 | #5 | |||
highly mean
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35
Не в сети |
Цитата:
Цитата:
Цитата:
|
|||