Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.07.2011, 23:34   #1
S-HaCK XORitY
Пользователь
 
Аватар для S-HaCK XORitY
 
Регистрация: 19.07.2011
Сообщений: 70
Вопрос Вопрос по SQL опытным программерам!

Доброго времени суток дорогие форумчане.

Данный пост на самом деле не имеет никаких ограничений, будь Вы опытный программист или нет, но боюсь с данной проблемой новичку не справиться.

Собственно вопрос: есть 3 таблицы в БД, в 1ой - записи о древе разделов, спроектированное по технологии Nested Sets (вложенные множества), во 2ой - записи сущности свойств, которые пользователь создает конкретно в каком то разделе, далее эта сущность распространяется на все его подразделы, и в 3ей табличке, содержаться значения свойств, относительно раздела и сущности свойства, так же в 3ей табличке может и не быть значения свойства, в таком случае берется значение по умолчанию, которое задается пользователем в сущности свойства.
Мне нужно сделать выборку из БД текущего раздела, всей родительской ветки, все сущности свойств относительно разделов на родительской ветку, а так же все значения из базы свойств относительно сущностей и в случае если свойства нет в базе свойств, подставить значение из сущности (то что по умолчанию), но это я уже делаю средствами php ниже sql запрос:


Код:
SELECT ise.*, isp.id as isp_id, isp.name as isp_name, isp.description as isp_description, isp.value as isp_value, pb.name as pb_name, pb.value as pb_value FROM `iblock_section` ise
left join
(
  select ise.depth_level, isp.* from iblock_section ise
  left join iblock_section_proper isp
  on (ise.id = isp.section_id)
  where left_key <= 3 and right_key >= 110 and isp.id > 0
) AS isp
on (isp.depth_level < ise.depth_level)
  left join proper_base pb
  on (ise.id = pb.id and isp.name = pb.name and pb.type = 'S')
where
  ise.iblock_type = 'catalog'
and
  ise.iblock_id = 11
and
  ise.parent_id = 42
Этот запрос обрабатывается в pma 6.7666 сек, а отображается ~35 сек, а в php скрипте еще дольше и чем больше данных и свойств, тем медленнее и дольше происходит обработка.
Подскажите пожалуйста, как можно оптимизировать данный запрос и возможно ли сделать замену значений (если есть в базе свойств, табличка 3, то вставлять значение из нее, а не то что по умолчанию), прямо в sql-запросе.

Да и на всякий случай, я использую php 5, mysql 5.1.41

Заранее спасибо за ВСЕ ответы!!!
Made All in China - MAC OS...

Последний раз редактировалось S-HaCK XORitY; 19.07.2011 в 23:59.
S-HaCK XORitY вне форума Ответить с цитированием
Старый 20.07.2011, 07:03   #2
Виталий Желтяков
Старожил
 
Аватар для Виталий Желтяков
 
Регистрация: 19.04.2010
Сообщений: 2,702
По умолчанию

Ваша задача хороший пример пагубного использования join. Избавляйтесь от него.
Виталий Желтяков вне форума Ответить с цитированием
Старый 20.07.2011, 08:42   #3
mv28jam
Старожил
 
Аватар для mv28jam
 
Регистрация: 09.09.2008
Сообщений: 2,624
По умолчанию

По этим данным сказать что-то сложно - ключейи и ндексов то мы не видим.
EXPLAIN сделайте и киньте сюда результат.
Стрелок-охотник
mv28jam вне форума Ответить с цитированием
Старый 20.07.2011, 09:58   #4
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Код:
left join (  select ise.depth_level
, isp.id, isp.name, isp.description, isp.value // другие поля не использованы в резулттате
               from iblock_section ise
               inner //в фильтре исп данные данные из этой табл
                     join iblock_section_proper isp on (ise.id = isp.section_id)  
                where left_key <= 3 
                  and right_key >= 110 
                  and isp.id > 0 // условие наличия дочерней  == inner ????
           ) AS isp on (isp.depth_level < ise.depth_level)
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 20.07.2011 в 10:03.
evg_m вне форума Ответить с цитированием
Старый 20.07.2011, 13:02   #5
S-HaCK XORitY
Пользователь
 
Аватар для S-HaCK XORitY
 
Регистрация: 19.07.2011
Сообщений: 70
По умолчанию

mv28jam извиняюсь, да действительно сложно понять без схематики и ключей.

Вот explain:
Безымянный.jpg

Далее схематика:
iblock.jpg

На данной схеме изображено информационное ветвление, таким алгоритмом спроектирован адаптивный интерфейс, на основе которого можно построить практически любую бизнес логику. Данная схема в системе, немного отличается от схемы на картинке, т.к. на картинке отсутствует Nested Sets и названия таблиц теперь в lowercase.

Виталий Желтяков:
Цитата:
Ваша задача хороший пример пагубного использования join. Избавляйтесь от него.
Я бы с радостью отказался, но что тогда использовать если не join? Цыклы? В таком случае время выполнения операции и нагрузка на БД увеличиться в разы и это точно не будет решением. Спасибо за совет, был бы признателен, за пояснение что именно использовать вместо left join.

P.S. До использование join'ов, действительно были циклы - это просто ужасно, работа производилась точно, но очень долго, а парой превышала max_execution_time = 30 и отваливалась. После переписывания (оптимизации) алгоритма, с использованием join'ов все ускорилось и отваливаться перестало, но иногда все равно тормозит и по прогнозам будет еще больше тормозить по мере увеличения базы, относительно данного алгоритма.
Made All in China - MAC OS...
S-HaCK XORitY вне форума Ответить с цитированием
Старый 20.07.2011, 13:05   #6
S-HaCK XORitY
Пользователь
 
Аватар для S-HaCK XORitY
 
Регистрация: 19.07.2011
Сообщений: 70
По умолчанию

Да и спасибо модераторам, за то что перенесли тему сюда. Я недавно здесь зарегистрировался и не углядел, раздел предназначенный именно для такого рода тем.
Made All in China - MAC OS...
S-HaCK XORitY вне форума Ответить с цитированием
Старый 20.07.2011, 13:41   #7
mv28jam
Старожил
 
Аватар для mv28jam
 
Регистрация: 09.09.2008
Сообщений: 2,624
По умолчанию

Цитата:
Вот explain:
Тяжелый случай .
Сразу без детального разбора скажу, что очень плохой запрос в плане производительности - только 1 из пяти операций делается по ключу. Для остальных СУБД "лопатит" всю таблицу. Поле type explain'а говорит о том, использовались ли для поиска/связи полей ключи. ALL говорит о том что СУБД читало всю таблицу для связи/поиска.
Вам нужно сделать так чтобы join'ы и where'ы работали по ключам или индексированным полям, тогда время выборки упадёт на порядок.

Понятно обьяснил?
Стрелок-охотник

Последний раз редактировалось mv28jam; 20.07.2011 в 13:46.
mv28jam вне форума Ответить с цитированием
Старый 20.07.2011, 14:23   #8
S-HaCK XORitY
Пользователь
 
Аватар для S-HaCK XORitY
 
Регистрация: 19.07.2011
Сообщений: 70
По умолчанию

Да mv28jam, все исчерпывающе понятно, но дело в том, что для получения нужного результата, используются следующие действия и правила, напрмер:

пользователь находится в под разделе с id 100, например на 5-ом уровне вложенности, в тот момент как на 4-ом ур. влож. созданы сущности свойств: color - цвет, length - длина, weight - вес, на 3-ем: price - Цена и все они действуют на 5-й уровень. Так же в этот момент у отображаемых разделов, являющихся подразделами относительно 5го уровня, есть свойства в базе свойств, относительно сущностей свойств.

Некоторые правила для получения результата:

1. Всегда должен быть определен тип-инфо блока - iblock_type, например: catalog
2. Всегда должен быть определен ID-инфо блока - iblock_id, например: 11
3. Тип инфо-блока и ID инфо-блока - это НЕ одно и тоже, и находятся они в разных таблицах, но запись о них есть везде на более низких уровнях, таких как, разделы и элементы.
4. ID раздела (section_id) не всегда определен, в случае если section_id, не указан, он равен 0, а разделы с таким section_id, являются корневыми, относительно ID инфо-блока, если section_id определен, то это подраздел и с него считывается левый и правый ключи, а затем вычисляется уровень вложенности и ветка родитель (parent_branch), по методу nested sets.
5. Относительно текущего раздела (в примере id = 100), выбираются все ПОД разделы.
6. Относительно текущего раздела и всей parent_branch, выбираются сущности свойств.
7. Относительно всех ПОД разделов и сущностей свойств, выбираются свойства из базы свойств (proper_base).
8. Свойство в proper_base, может и не быть, в таком случае берется значение из сущности свойства (по умолчанию).
9. Подстановка и группировка значений.

Из выше указанных правил следует: что изначально определить все сущности свойств невозможно, а так же невозможно определить значения из proper_base, т.к. их может и не быть.

Я сейчас сам очень в плотную занимаюсь оптимизацией данного алгоритма, я уже кое что придумал, но пока что не полностью, как что то получиться, обязательно выложу здесь. Думаю это довольно интересная тема, т.к. каждый программист хоть раз в своей жизни, но сталкивается с разработкой сложного ПО или CMS, в моем случае я разрабатываю CMS, а точнее уже разработал, теперь дело за оптимизацией)))

Спасибо за совет mv28jam!
Made All in China - MAC OS...
S-HaCK XORitY вне форума Ответить с цитированием
Старый 20.07.2011, 14:40   #9
mv28jam
Старожил
 
Аватар для mv28jam
 
Регистрация: 09.09.2008
Сообщений: 2,624
По умолчанию

Цитата:
что для получения нужного результата, используются следующие действия и правила, напрмер
Я собственно про логику работы и построение запроса не говорю. Разбираться в логике у меня просто нет времени.
Я говорю о том что при существующем запросе в уже существующих таблицах надо сделать индексацию необходимых для работы запроса полей.

Например section_id,left_key,right_key ключи/индексы?
Стрелок-охотник
mv28jam вне форума Ответить с цитированием
Старый 20.07.2011, 14:50   #10
S-HaCK XORitY
Пользователь
 
Аватар для S-HaCK XORitY
 
Регистрация: 19.07.2011
Сообщений: 70
По умолчанию

Да да это я понял, за этот совет большое спасибо! Но логику я описал на всякий, может кто нибудь решиться разобраться в этом, ну мало ли, у меня такое бывает, конечно если есть время. mv28jam - если бы я знал как, то поставил тебе +, за потраченное время и дельный совет)

по поводу left_key и right_key они index, а вот section_id нет
Made All in China - MAC OS...
S-HaCK XORitY вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Интересное предложение опытным программистам MaxRiga Фриланс 7 24.03.2010 11:58
Абстрактные классы. Опытным взглядом на 1 минуту работы Metal_666_ Общие вопросы C/C++ 5 15.02.2010 12:28
вопросик самым опытным :-) Doholyan Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 25.08.2009 17:13