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

Форум MySQL

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

 

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

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

тема: Что за хитрый запрос??
 
 автор: Anwor   (10.08.2006 в 10:33)   письмо автору
 
 

Всем добрый день.
У меня проблема следующего плана...
Есть запрос. Только не пугайтесь.

<?sql
$sql
="SELECT
    file.id as id, 
    file.name as name, 
    file.date_cr as date_cr, 
    file.date_ed as date_ed, 
    file.note as note 
FROM 
    file, 
    role_, 
    ownerrole_userrole, 
    cross_role_user, 
    folder, 
    user_, 
    grant_role, 
    person, 
    subject, 
    cross_subject_person, 
    cross_folder_subj 
 WHERE (
file.folder_id="
.$row_fold['id'].
AND role_.privileged=1 
AND cross_role_user.role_id=role_.id 
AND cross_role_user.user_id="
.$_SESSION['USER']."                
)
) OR (                        
file.folder_id="
.$row_fold['id'].
AND file.id=ownerrole_userrole.file_id 
AND (
(
ownerrole_userrole.owner_role_id=
$value
) OR (
ownerrole_userrole.owner_role_id=role_.id 
AND role_.privileged=-1 
AND user_.id="
.$_SESSION['USER'].
AND user_.person_id=cross_subject_person.person_id 
AND cross_subject_person.subject_id=subject.id 
AND cross_folder_subj.subj_id=subject.id 
AND cross_folder_subj.folder_id="
.$row_fold['id']."
)
)
) OR (                        
file.folder_id="
.$row_fold['id'].
AND file.id=ownerrole_userrole.file_id 
AND ownerrole_userrole.ouselect=1 
AND (
(
ownerrole_userrole.role_id=
$value 
AND cross_role_user.user_id="
.$_SESSION['USER'].
AND cross_role_user.folder_id="
.$row_fold['id'].
AND cross_role_user.role_id=
$value
) OR (
ownerrole_userrole.role_id=role_.id 
AND role_.privileged=-1 
AND user_.id="
.$_SESSION['USER'].
AND user_.person_id=cross_subject_person.person_id 
AND cross_subject_person.subject_id=subject.id 
AND cross_folder_subj.subj_id=subject.id 
AND cross_folder_subj.folder_id="
.$row_fold['id']."
)
)
)
GROUP BY 
file.id"
;
$res2=mysql_query($sql);
?>

Как видите, запрос берет огромное количество параметров из кучи таблиц. Всё это приводит к тому, что МуСкул выводит тысячи строк с одинаковым результатом, если бы не GROUP BY. С ним всё получается. Но фигня такая: если запрос возвращает хоьт 1 результат, то скрипт ООООЧЕНЬ сильно начинает тормозить. Имеется в виду, при загрузке. Такое ощущение, что несмотря на GROUP BY он передает через канал все эти тысячи строк, и только потом, у клиента, группирует их как надо. Каким макаром можно оптимизировать запрос, чтобы не было таких тормозов? Может, стоит разбить на несколько более мелких??

   
 
 автор: RV   (10.08.2006 в 12:27)   письмо автору
 
   для: Anwor   (10.08.2006 в 10:33)
 

я думаю вы просто обязаны его разбить на более мелкие

   
 
 автор: Anwor   (10.08.2006 в 15:37)   письмо автору
 
   для: RV   (10.08.2006 в 12:27)
 

Но... я бы хотел оставить такую организацию, поскольку если разбить это на 55 запросов, то потом вряд ли удастся собрать все данные в единый контейнер...
Понимаете, дело в том, что мне интересен сам механизм передачи переменных в РНР при GROUP BY. Ведь группировка должна происходить уже на стороне сервера, и количество строк тоже определяется там.
ЗЫ: если использовать PHPMyAdmin, то выполнение запроса не занимает много времени, а вот сам скрипт выводит несчастные 4 строчки добрых 20 секунд, тогда как остальные РНР-модули загружаются мгновенно =/

   
 
 автор: Trianon   (10.08.2006 в 15:49)   письмо автору
 
   для: Anwor   (10.08.2006 в 15:37)
 

С чего Вы решили, что запрос выполняется мгновенно?

   
 
 автор: RV   (10.08.2006 в 16:47)   письмо автору
 
   для: Trianon   (10.08.2006 в 15:49)
 

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

   
 
 автор: Anwor   (10.08.2006 в 17:11)   письмо автору
 
   для: Trianon   (10.08.2006 в 15:49)
 

Знаете, вы были правы, я перепутал количество секунд с каким-то другим сложным запросом.. этот выполняется 34 секунды =)))) Вот тебе и лаг при передаче - передает-то он всё как надо.
А это действительно в большей степени зависит от количества используемых в запросе таблиц?

   
 
 автор: cheops   (10.08.2006 в 17:19)   письмо автору
 
   для: Anwor   (10.08.2006 в 17:11)
 

>А это действительно в большей степени зависит от количества используемых в запросе таблиц?
Да, так как СУБД сначала объединяет все таблицы, что приводит к колоссальном объёму памяти, которое зачастую сбарсываются на жёсткий диск (что ещё больше усугубляет ситуацию), потом СУБД начинает рыться в этих данных - их очень много и на перелопачивание уходит значительное время. Это при том, что подавляющее большинство полученных данных приходится отбрасывать - в результирующую таблицу идут доли процента сгенерированного массива.

   
 
 автор: hars   (10.08.2006 в 17:20)   письмо автору
 
   для: Anwor   (10.08.2006 в 17:11)
 

Думаю лучше свести эти 11 таблиц к разумному количеству,либо и правда придётся вам писать несколько отдельных запросов,а если база растёт,то у вас такой запрос не 34 секунды будет выполняться ,а все 34 часа :)

   
 
 автор: Anwor   (10.08.2006 в 17:45)   письмо автору
 
   для: hars   (10.08.2006 в 17:20)
 

Вот это нифига себе, перспективка.. ))
А если мне оставить те же 11 таблиц, но сильно упростить проверяющие условия? Имеется в виду, провести сначала несколько уточняющих запросов по всяким там айдишникам, а потом уже подставить под знаки равно тупо числа? Или такое всё равно не поможет?

ЗЫ: к сожалению, я уже не смогу реконструировать БД, потому как весь сайт уже готов, всё там между собой связано, и изменения в таблицах повлекут кошмарные изменения в движке. Надо мне как-то по-другому провернуть...

   
 
 автор: cheops   (10.08.2006 в 18:20)   письмо автору
 
   для: Anwor   (10.08.2006 в 17:45)
 

С ростом объёма любой из таблиц скорость будет только падать, так как линейный рост объёма в любой из таблиц при 11-табличном запросе будет приводить к экспоненциальному росту объёма вычислений.

   
 
 автор: Trianon   (10.08.2006 в 18:50)   письмо автору
 
   для: Anwor   (10.08.2006 в 17:45)
 

примерно в таком направлении и надо двигаться...
во всяком случае, если не удастся упростить запрос другими способами.

   
 
 автор: Anwor   (11.08.2006 в 12:29)   письмо автору
 
   для: Trianon   (10.08.2006 в 18:50)
 

То есть как я понял, политика "много мелких запросов" более выигрышная, чем "один здоровый"? Даже если по сути они дадут один и тот же результат?

   
 
 автор: Trianon   (11.08.2006 в 12:34)   письмо автору
 
   для: Anwor   (11.08.2006 в 12:29)
 

В общем случае, политика "много мелких запросов" менее выигрышна, чем "один здоровый запрос", но более выигрышна, чем "один дохлый запрос".

   
 
 автор: Anwor   (11.08.2006 в 15:26)   письмо автору
 
   для: Trianon   (11.08.2006 в 12:34)
 

))))
Это я понимаю, но:
1) Запрос таки выполняется, хоть и через Ж...
2) Мне как раз и интересно, не приведет ли увеличение количества запросов, которые по сути в сумме дадут такую же кучу информации, к еще большим временным затратам?

   
 
 автор: Trianon   (11.08.2006 в 15:30)   письмо автору
 
   для: Anwor   (11.08.2006 в 15:26)
 

Все определяется спецификой организации взаимосвязей таблиц в конкретной БД.
Да и большой запрос тоже можно написать по-разному.

   
 
 автор: cheops   (11.08.2006 в 18:13)   письмо автору
 
   для: Anwor   (11.08.2006 в 12:29)
 

>То есть как я понял, политика "много мелких запросов" более
>выигрышная, чем "один здоровый"? Даже если по сути они дадут
>один и тот же результат?
Такая политика выгодна, если у вас большой объём данных и чем больше размер таблицы, тем выгоднее становится использовать элементарные запросы вместо объединений.

   
 
 автор: cheops   (10.08.2006 в 16:46)   письмо автору
 
   для: Anwor   (10.08.2006 в 10:33)
 

FROM  
    file,  
    role_,  
    ownerrole_userrole,  
    cross_role_user,  
    folder,  
    user_,  
    grant_role,  
    person,  
    subject,  
    cross_subject_person,  
    cross_folder_subj 

20 секунд для 11-табличного запроса - это очень не плохо... Обычно больше 4 табличных запросов стараются не использовать, так как нагрузка на базу данных возрастает капитально.

   
Rambler's Top100
вверх

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