Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Нужно оптимизировать запрос со сложным условием
 
 автор: mikhailk   (23.11.2006 в 20:43)   письмо автору
 
 

Имеются три таблицы

dept: id,naim - департаменты
otdl: id,id_dept,naim - отделы в них
grup: id,id_otdel,naim - группы в отделах

полный список подразделений получается перемножением:

SELECT * FROM dept,otdl,grup
WHERE dept.id=otdl.id_dept
AND otdl.id=grup.id_otdel


сверху на это наложены условия доступа:

dostup: user,level_podr,id_podr

Например:

'ivan','dept',1 - доступ к департаменту 1 и всем его отделам и группам
'ivan','dept',2 - доступ к департаменту 1 и всем его отделам и группам
'serg','otd',88 - доступ к отделу 88


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

SELECT * FROM dept,otdl,grup,dostup
WHERE dept.id=otdl.id_dept
AND otdl.id=grup.id_otdel

AND dostup.user='current_user'
AND
(
dostup.id_podr=dept.id AND dostup.level_podr='dept'
OR dostup.id_podr=otdl.id AND dostup.level_podr='otdl'
OR dostup.id_podr=grup.id AND dostup.level_podr='grup'
)


В итоге получается таблица размером dept х otdl х grup х dostup, на которую потом накладывается блок условий. Работает задумчиво, а с некоторого количества записей (особенно в таблице dostup) явно тормозит.

Можно как-нибудь оптимизировать этот запрос?
В принципе, можно разделить таблицу доступа на три, но не уверен, что это поможет принципиально.

Можно придумать какой-нибудь трюк, но в итоге все равно должен получиться один запрос, который выдает набор записей.

   
 
 автор: Trianon   (23.11.2006 в 21:16)   письмо автору
 
   для: mikhailk   (23.11.2006 в 20:43)
 

А индексы все расставлены?
Еще я бы соединения на синтаксис JOIN ... ON переписал... и поглядел бы на поведение...

   
 
 автор: mikhailk   (24.11.2006 в 09:17)   письмо автору
 
   для: Trianon   (23.11.2006 в 21:16)
 

Индексы расставлены.
С синтаксисом JOIN ... ON у меня не получилось. Возможно, MySQL старый, а проапгрейдить сейчас его у меня возможности нет.

Может как-нибудь иначе организовать фильтрацию по доступу?

   
 
 автор: Trianon   (24.11.2006 в 09:57)   письмо автору
 
   для: mikhailk   (24.11.2006 в 09:17)
 

А какая у Вас версия сервера?

   
 
 автор: mikhailk   (24.11.2006 в 12:08)   письмо автору
 
   для: Trianon   (24.11.2006 в 09:57)
 

4.0.18

   
 
 автор: Trianon   (24.11.2006 в 12:48)   письмо автору
 
   для: mikhailk   (24.11.2006 в 12:08)
 

Не первая свежесть, но и не совсем отстой. JOINы есть даже в третьей версии.
Вашему запросу соответствует что-то такое:

SELECT * 
FROM dept 
  JOIN otdl ON dept.id=otdl.id_dept 
  JOIN grup ON otdl.id=grup.id_otdel
  JOIN dostup ON dostup.level_podr=
    (CASE dostup.level_podr 
       WHEN 'dept' THEN dept.id 
       WHEN 'otdl' THEN otdl.id 
       WHEN 'grup' THEN grup.id
    END)
WHERE dostup.user='current_user' 

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования