Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Интернет » Web-программирование » Оптимизация запроса MySQL

Модерирует : Cheery

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6

Открыть новую тему     Написать ответ в эту тему

israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
andead, дорогой! Вы не представляете, как я Вам благодарен!!!! Сначала я зациклился на "Using filesort", читал статьи, плясал с бубном.... В голове у меня окончательно всё перемешалось. Дело в том, что програмирование я учил очень быстро, так сложились обстаятельства. И целые области оказались пропущенными. Опримизация запросов к базе данных - вообще область новая для меня. И вдруг свалилось! И надо было срочно сделать, сайт висел, клиент бился головой об стену. Но вопрос то не простой. Не возможно в последнюю ночь перед экзаменом выучить то, что пропускал в течении всей сессии.  
Запросы, как Вы видите, у меня сложные. Отделаться от "Using filesort" при наличии и "GROUP BY" и "ORDER BY " практически невозможно....
И вот, совсем было отчаявшись, и вспомнил про Ваш совет посмотреть время выполнения запроса в том и в другом случае. И просто о....л!!!! Если в первом случае время составило 7!!!!!! секунд,  то во втором случае оно составило 0.8 секунд!!!! Я быстренько всё поправил. Клиент вернулся к жизни .
Короче, если только Вы и уважаемый Cheery будете в наших краях, с меня  причитается!
 

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 16:28 30-10-2009
andead



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
всегда пожалуйста) на самом деле 0,8 секунд это всё равно очень многа для sql запроса, нужно либо менять метод сбора статистики о просмотрах, либо прикручивать кеширование

Всего записей: 1821 | Зарегистр. 22-09-2005 | Отправлено: 16:44 30-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Попробовал последовать совету andead. Переделал запрос, так, что бы обходиться обращением только к одной таблице. Но GROUP BY и ORDER BY всё равно остались… И видимо как результат – «Using filesort» и время – 0.4 секунды.  
Вот таблица с отчётом –  
http://rapidshare.com/files/300112681/__________.htm.html  
Вопрос – что делать, что бы время сократилось до приемлемого? Придумывать составной индекс?

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 21:33 30-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Сайт продолжает падать, и я продолжаю поиски....
Вот кусок кода, в нём я обращение к базе данных поместил в цикл. Цикл повторяется порядка 40 раз.

Код:
foreach ($BindArray as $val){
   $keywords_search = explode(",", $val['keywords']);
   $match = array_intersect($keywords_search, $keywords_pattern);
   if(count($match) > 6) {
          $SQLUPDATE = "UPDATE `tbl_photos` SET `similar_pictures`=".count
           WHERE `photo_id` = '".$val['photo_id']."'";
            $this->tep_mysql_query($SQLUPDATE);
   }
}

Вопрос. Может ли быть обращение к базе в цикле как у меня критичным? Настолько, что бы уронить сайт?

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 14:47 02-11-2009
andead



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
не легче ли вам пропустить скрипт через профайлер и посмотреть узкие места, чем тыкать пальцем в небо? хороший профайлер есть в NuSphere PhpED

Всего записей: 1821 | Зарегистр. 22-09-2005 | Отправлено: 16:47 02-11-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Понял. Давно уже об этом думал. Но не знал, как приступить. Спасибо, буду пробовать.

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 16:51 02-11-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Пипл, помогите!  
На компе локально под ХРю стоит Апач, РНР, MySQL .
Включил опцию Slow Query Log. Включилось всё вроде корректно, судя по переменным, список переменных привожу –  
Подробнее...
Запускаю страничку, где запрос гарантированно выполняется 15!!!!! секунд. Но файл «slowquery.log» на компе не нахожу!  
Где же может быть ошибка???  
 

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 10:01 04-11-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Ошибка

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 15:25 04-11-2009 | Исправлено: israel_rider, 18:14 04-11-2009
rtyug



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
1) подскажите как оптимизировать такой запрос в один запрос?
 
как-то через join делают... тут  http://www.sql.ru/forum/actualthread.aspx?tid=678367
 

Код:
 
   
    $c->model('DBI')->dbh->do(
        'DELETE from friends                              
                  WHERE id_un = ?
                  AND id_un_friends = ?   );
 
    $c->model('DBI')->dbh->do(
        'DELETE from friends                              
                  WHERE id_un = ?
                  AND id_un_friends = ?   );
 
             
             
    $c->model('DBI')->dbh->do(
        'DELETE from send_friends                              
                  WHERE id_un = ?
                  AND id_un_friends = ? );
 
    $c->model('DBI')->dbh->do(
        'DELETE from send_friends                              
                  WHERE id_un = ?
                  AND id_un_friends =? );
                   
                   
 

 
2) тут нужно это написать одном запросом или можно много маленьких запросов делать?
 
Добавлено:
если нужно удалить несколько записей, то тут будет вот так?
 

Код:
 
    $c->model('DBI')->dbh->do(
        'DELETE from friends AS t1,
                            send_friends AS t2
                                                           
                  WHERE ( t1.id_un = ' . $c->user->{user}->{id} .'
                  AND t1.id_un_friends = '. $id_un.'
                  ) OR (
                  t1.id_un = ' . $id_un  .'
                  AND t1.id_un_friends = '. $c->user->{user}->{id}.'
                  )
                  OR                  
                  ( t2.id_un = ' . $c->user->{user}->{id} .'
                  AND t2.id_un_friends = '. $id_un.'
                  )  
                  OR  
                  (
                  t2.id_un = ' . $id_un  .'
                  AND t2.id_un_friends = '. $c->user->{user}->{id}.'
                  }' );
 

 
это правильно?
 
 
НО, вопрос, если в этих 2 таблицах нужно удалить несколько элементов с оператором OR правильно?
 
Добавлено:
UPD: этот запрос не работает, вопрос остается, как оптимизировать? подскажите пожалуйста
 
была ошибка
 

Код:
 
delete_friend "DBD::mysql::db do failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE ( t1.id_un = 33
                  AND t1.id_un_friends = 1
                  ) OR (
  ' at line 4 at
 


Всего записей: 490 | Зарегистр. 13-05-2009 | Отправлено: 09:26 17-11-2009
LFO

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
$c->model('DBI')->dbh->do(
        'DELETE from friends                              
                  WHERE id_un = ?
                  AND id_un_friends = ?   );
 
    $c->model('DBI')->dbh->do(
        'DELETE from friends                              
                  WHERE id_un = ?
                  AND id_un_friends = ?   );
 
             
             
    $c->model('DBI')->dbh->do(
        'DELETE from send_friends                              
                  WHERE id_un = ?
                  AND id_un_friends = ? );
 
    $c->model('DBI')->dbh->do(
        'DELETE from send_friends                              
                  WHERE id_un = ?
                  AND id_un_friends =? );  

можно объединить и в 1 запрос.. просто нужно перечислять все условия..  
DELETE from send_friends WHERE ( (id_un = ? AND id_un_friends = ?) and (id_un = ? AND id_un_friends = ?) )
но стоит ли, зависит от того, сколько запоросов на удаления

Всего записей: 16 | Зарегистр. 14-11-2009 | Отправлено: 15:41 17-11-2009
rtyug



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
LFO
 
это понятно, а с двух таблиц можно ли удалить, я в предыдущем посту хотел спросить именно это
 

Цитата:
но стоит ли, зависит от того, сколько запоросов на удаления  

 
может быть всего штук 10 с 2-4 таблиц
 
как правильнее:
тут нужно это написать в одном запросом или можно много маленьких запросов делать?
 
 
 

Всего записей: 490 | Зарегистр. 13-05-2009 | Отправлено: 21:54 17-11-2009 | Исправлено: rtyug, 22:11 17-11-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Отловил профайлером тормозящий запрос. Вот он:
 
SELECT hash,  
(SELECT COUNT( photos.hash ) FROM photos WHERE photos.hash = uploads.hash) AS count
FROM uploads HAVING count=0
 
Время - 0.6 сек. Вроде многовато...  
Вопрос. Можно ли его переписать подругому?

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 10:34 28-11-2009 | Исправлено: israel_rider, 10:39 28-11-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
SELECT uploads.hash, tmp.cnt FROM uploads, (SELECT hash, COUNT(hash) cnt FROM photos GROUP BY hash) tmp WHERE tmp.cnt=0 AND uploads.hash=tmp.hash
может быть сообщение об ошибке, но что то в этом роде
чтобы этот запрос по подсчету выполнялся один раз

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 21:56 28-11-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Cheery, плиз, можно ссылочку, где можно почитать, что это -
tmp.cnt  
такое? Или хотя бы название этого, что бы вбить в Гугл.
cnt это алиас, это понятно. а tmp ?
Извиняюсь, вроде понял, tmp это тоже алиас. Просто я привык, что алиасы пишут через AS
 
Добавлено:
Вообще то, в мануале написано, что всё это делается гораздо проще.  
Подробнее...
Но проблема в том, что у меня в таблице то как раз поле hash объявлено как NULL. А менять на NOT NULL стрёмно.

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 22:07 28-11-2009 | Исправлено: israel_rider, 22:12 28-11-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
israel_rider

Цитата:
Просто я привык, что алиасы пишут через AS

это необязательно.

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 22:23 28-11-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
MySQL returned an empty result set (i.e. zero rows). ( Query took 0.0837 sec )

Cheery, огромный сенкс, только ещё разобраться в нём до конца надо.

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 22:27 28-11-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
israel_rider

Цитата:
MySQL returned an empty result set (i.e. zero rows). ( Query took 0.0837 sec )  

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

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 23:22 28-11-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Да нет же! Всё правильно. Старый запрос работал точно так же. Это запрос, что бы находить поля, заполненые только в одной таблице, и не имеющие соответствия во второй. В данный момент все записи исправны, поэтому, естественно, запрос ни чего находить не должен.

Всего записей: 926 | Зарегистр. 28-07-2007 | Отправлено: 23:28 28-11-2009
UncoNNecteD



Silver Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Давайте еще про оптимизацию:
Есть таблица
country    smallint(5)  
city    smallint(5)  
typeid    smallint(5)  
datefill    mediumint(8)  
num    float(8,2)  
kod    int(11)
Записей около 350 000.
 
индексы определены:
Primary:
country  
city  
typeid  
datefill
 
trrindex)
typeid  
city  
country
 
reg_df: (index)
datefill  
country
 
Запрос, выбирает последнюю дату, для которой есть запись о статистике по нужной country:
SELECT `datefill` FROM `tablestat`
WHERE `country` = '123'  
ORDER BY `datefill` DESC  
LIMIT 1
 
Работает медленно (до 0.5 сек)
Предложения по оптимизации?

----------
-= Я тут чертовски давно =-

Всего записей: 4040 | Зарегистр. 21-03-2002 | Отправлено: 11:25 17-12-2009 | Исправлено: UncoNNecteD, 11:36 17-12-2009
andead



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Предложения по оптимизации?

CREATE TABLE скопируйте сюда, и EXPLAIN запроса желательно

----------
мой блог

Всего записей: 1821 | Зарегистр. 22-09-2005 | Отправлено: 19:06 17-12-2009
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6

Компьютерный форум Ru.Board » Интернет » Web-программирование » Оптимизация запроса MySQL


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2025

LiteCoin: LgY72v35StJhV2xbt8CpxbQ9gFY6jwZ67r

Рейтинг.ru