Старый 23.09.2014, 15:36   #1   
Форумец
 
Сообщений: 6,684
Регистрация: 26.04.2006
Возраст: 44

Eвгений вне форума Не в сети
Иерархический запрос в 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

silly вне форума Не в сети
Цитата:
Сообщение от Eвгений Посмотреть сообщение
В конечном проекте количество каталогов вряд ли превысит 500, а вот элементов будет около 100 000.
Каталог или каталоги?

Цитата:
Сообщение от Eвгений Посмотреть сообщение
Его выполнение заняло 0.0042 сек. ... То есть при наихудшем раскладе 0.42 сек на полный анализ.
Не думаю. Кэши, буферы и т. д. (Или это про id in (…) было?)

Цитата:
Сообщение от Eвгений Посмотреть сообщение
Хостер на меня не обидится?
Э… выделенный сервер? (Можно не отвечать.)

Цитата:
Сообщение от Eвгений Посмотреть сообщение
Вы бы стали оставлять так как есть?
Postgres наверно бы взял…

Последний раз редактировалось silly; 23.09.2014 в 20:37.
  Ответить с цитированием
Старый 23.09.2014, 20:42   #3   
Форумец
 
Сообщений: 6,684
Регистрация: 26.04.2006
Возраст: 44

Eвгений вне форума Не в сети
silly,
Цитата:
100 000 чего?
Элементов во второй таблице. Которые принадлежат узлам дерева (каталога) в первой таблице.
Я к чему это написал - 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

Eвгений вне форума Не в сети
Хм... а ведь в Nested Sets это будет даже проще и точно быстрее. Нужно просто выбрать записи, где разница между leftkey и rightkey не больше единицы - это и будут концевые, "бездетные" узлы.
Но этой процедурой мы лишь избавляем MySQL от 400 запросов.
Но еще нужно выбрать в таблице №2 все элементы, принадлежащие одному из 400 идентификаторов, полученных в предыдущем запросе.
  Ответить с цитированием
Старый 23.09.2014, 20:57   #5   
highly mean
 
Сообщений: 1,128
Регистрация: 26.05.2011
Возраст: 35

silly вне форума Не в сети
Цитата:
Сообщение от Eвгений Посмотреть сообщение
Я к чему это написал - MySQL при запросе будет анализировать каждую из 100 тыс записей на предмет соответствия parent_id каждой записи одному из 400 идентификаторов. 1500 записей анализщируется за 0.0042 сек.
Просто индекс на parent_id поставь, в 100 раз медленней не будет.

Цитата:
Сообщение от Eвгений Посмотреть сообщение
Нет, какой-нибудь обычный бюджетный. Уж ответьте, я еще раз говорю - сильно отстал от жизни, да и тогда не приходилось работать с огромными базами. Если Вам что-то смешно, то мне нет, уж будьте добры, без иронии.
Заметят — выгонят (без иронии).

Цитата:
Сообщение от Eвгений Посмотреть сообщение
В смысл Nested Set въехал. По сути это та же рекурсия, мой скрипт проходит по дереву каталога тот же путь, что и leftkey и rightkey.
Только у моего скрипта это как-то само получается, а тут все разжевывать надо.
Пытаюсь понять, насколько MySQL будет быстрее с этим справляться.
Если в первой таблице всего 500 записей, то выбрать их все одним запросом, построить дерево в программе, сложить результат в кэш.
  Ответить с цитированием
Поиск в теме: 



Быстрый переход:

  Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Support by DrIQ & Netwind