За последние 24 часа нас посетил 20331 программист и 1095 роботов. Сейчас ищут 357 программистов ...

Оптимизация SQL запроса и PHP кода

Тема в разделе "Прочие вопросы по PHP", создана пользователем vayas, 19 фев 2013.

  1. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    offtopic:
    1. при аутентификации неплохо бы делать trim для логина и пароля. замучался входить ))) копи-паста лишний пробел подставляла.
    2. цвета на графике не соответствуют тем, что в легенде указаны

    На каждое "объявление" надо получить три самые свежие записи из "статистики", так? связь по of_obj_relaty.id=obj_statistic.obj_id? а user_id для связи вообще не нужен, кажется.

    Мне кажется твой скриншот демонстрирует ошибку: логично предположить, что одна запись статистики показывает данные по заданному объявлению за один день. То есть можно объявить unique key(obj_id, date), а у тебя дата повторяется. Я неправ?
    Сделай уникальный индекс. Правильные ограничения избавят от странных ошибок.
     
  2. vayas

    vayas Активный пользователь

    С нами с:
    13 дек 2012
    Сообщения:
    167
    Симпатии:
    9
    Адрес:
    Пермь
    Да это нужно пофиксить.
    Он в целях безопасности, что бы пользователь не смог отправить ajax запрос, с другим ID объявления. Поэтому пользователь получает только свои ID.
    Совершенно верно.
    Нет там все правильно, обрати внимание на дату, она как раз увеличивается ровно на 1 день (четвертое и пятое число слева меняются)

    Добавлено спустя 9 минут 40 секунд:
    Блин я уже голову сломал как решить эту проблему,
    По ходу придется использовать memcached, обновляя его пару раз в день для актуализации.
    Просто всего пользователей несколько тысяч и объявлений примерно в 50 раз больше.
     
  3. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    А точно! Был невнимателен.

    Кстати, в первом посте GROUP BY не нужен и вообще ошибочен. Просто MySQL такие косяки прощает.
     
  4. vayas

    vayas Активный пользователь

    С нами с:
    13 дек 2012
    Сообщения:
    167
    Симпатии:
    9
    Адрес:
    Пермь
    Он то же нужен ) так как у одного объявления может быть несколько картинок.
    Соответсвено если я достаю одно объявление, у которого будет 5 картинок оно про дублируется.
    А мне надо 10 уникальных объявлений с одной любой картинкой. Таблица с картинками это отдльная таблица

    Добавлено спустя 6 минут 28 секунд:
    Кстати ещё вот этот блок с каждой итерацией генериться постоянно.
    Код (Text):
    1.  
    2. <script type="text/javascript">
    3.     google.load("visualization", "1", {packages:["corechart"]});
    4.     google.setOnLoadCallback(drawVisualization);
    5.     function drawVisualization() {          
    6.             var json = [['Имя', 'Метросфера показы', 'Метросфера просмотры', 'РКК просмотры', 'РКК показы'],
    7.              <?php echo ($rows == '') ? "['0',0,0,0,0]," : $rows; ?>]
    8.               var data = google.visualization.arrayToDataTable(json);
    9.               var ac = new google.visualization.ComboChart(document.getElementById('visualization-<?= $i ?>'));
    10.               ac.draw(data, {  
    11.                       width: 170,
    12.                        height: 55
    13.                });
    14.      }
    15. </script>
    16. <div id="visualization-<?= $i ?>" ></div>
    Ведь это то же большая проблема в разметке генериться 10 одинаковых функций с разными данными
    Как сделать рефакторинг этому, то же не знаю, сделать бы что то типо такого drawVisualization(divID, data)
    Но как тогда её вызывать с такими параметрами, google.setOnLoadCallback(drawVisualization); Ответа я так и не нашел.
     
  5. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    Вот какой запрос получился для MySQL:
    Код (Text):
    1.  
    2. SELECT q.*
    3. FROM (
    4.   SELECT s.*, @rn := CASE WHEN ISNULL(@prev) OR @prev <> s.obj_id THEN 1 ELSE @rn + 1 END AS rn, @prev := obj_id
    5.   FROM obj_statistic AS s
    6.   WHERE s.obj_id IN(13,14,16)
    7.   ORDER BY s.obj_id, s.date DESC
    8. ) AS q
    9. WHERE q.rn <= 3
    Если бы в MySQL была функция row_number() было бы попроще ))) а так приходится через локальные переменные выкручиваться
    s.obj_id IN(13,14,16) это "номера объявлений, упомянутые на этой странице". см. выше пост про 11 или 2 запроса

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

    Добавлено спустя 9 минут 41 секунду:
    Еще раз: твой синтаксис с GROUP BY ошибочный! БД его проглотила и не подавилась, но это потому что мускуль такой "демократичный" (зависит от настроек, кстати). Когда скармливаешь ошибочный синтаксис, жди неожиданных результатов.

    В общем когда кака с картинками вылезет -- пиши, отельно разберемся. )))
     
  6. vayas

    vayas Активный пользователь

    С нами с:
    13 дек 2012
    Сообщения:
    167
    Симпатии:
    9
    Адрес:
    Пермь
    СПАСИБО ТЕБЕ ))))))))))))) ВОТ ЭТО УДАР ))))) ВОТ ЭТО ВЗРЫВ...
    Я да же не знал что можно использовать локальные переменные в mysql.
    Вот это да, это просто круто ) Мне на каком-то форуме сказали что типо в MySQL нельзя использовать переменные.
    И я повелся. Вот блин...
    Вдруг будешь в Перми, звони с меня ПИВО )))))))))))

    Добавлено спустя 1 минуту 51 секунду:
    PHP.RU FOREVER!!!!!!!!!!! )))))))))))))))))
     
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    Ну я как-то ездил в Пермь, дорога от Е-бурга больно плохая )
     
  8. vayas

    vayas Активный пользователь

    С нами с:
    13 дек 2012
    Сообщения:
    167
    Симпатии:
    9
    Адрес:
    Пермь
    Ты с Е-бурга, я там не был не разу, говорят там лучше кто туда ездил из Перми...
    А как там кстати по работе, ну так средняя зарплата у программистов?
    Здесь в Перми например, примерно 30-50 тыс. Кто только начинает примерно 15 тыс.
    Есть кто получает и по 80 - 100 у меня знакомый, но он правда на C#
    А так по php вот то что я назвал выше, я сам занимаюсь этим ещё только полтора года )
    Постигаю как говорится все прелести.
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    вложенный селект это тоже беда.
     
  10. vayas

    vayas Активный пользователь

    С нами с:
    13 дек 2012
    Сообщения:
    167
    Симпатии:
    9
    Адрес:
    Пермь
    Но явно не такая, как 10 лишних запросов?
    Да и в любом случае какое ещё может быть решение этого вопроса, я думаю это предел в данном случае?
    Если только как то перестраивать архитектуру таблиц, ну я не знаю.
    Если есть мысли по этому поводу с радостью прочитал бы.
     
  11. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    когда как
    вложенный селект будет выполнен много раз. т.е. пока это ещё не два запроса.

    а можно его выдрать и сделать несколько запросов без сложных условий, как я тебе предлагал. но это ты сам должен наморщить лоб уже.
     
  12. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    igordata, В общем случае нет. Параметризованный вложенный запрос был БЫ выполнен много раз. В данном случае будет один проход [ по индексу, если есть составной (obj_id, date) ].

    vayas, я из Челябинска. Просто в Пермь надо ехать через Екатеринбург. От нас до Е-бурга 200км более-менее приличной дороги, а вот от Е-бурга до Перми ~400км ужас-ужас! :)

    Зарплаты в Челябинске наверное такие же как в Перми. В Е-бурге повыше.

    Добавлено спустя 2 минуты 45 секунд:
    У нас проживание дешевле чем в Екатеринбурге, так что одно на одно и выходит.
     
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    прекрасно если так =)
     
  14. vayas

    vayas Активный пользователь

    С нами с:
    13 дек 2012
    Сообщения:
    167
    Симпатии:
    9
    Адрес:
    Пермь
    Благодаря ответам на гугле и форуме javascript удалось решить ещё одну проблему. А именно
    Код (Text):
    1.  
    2. Вот эта функция в цикле генериться, десть раз.
    3. google.load("visualization", "1", {packages:["corechart"]});
    4. google.setOnLoadCallback(drawVisualization);
    5. function drawVisualization() {          
    6.            var json = [['Имя', 'Метросфера показы', 'Метросфера просмотры', 'РКК просмотры', 'РКК показы'],
    7.             <?php echo ($rows == '') ? "['0',0,0,0,0]," : $rows; ?>]
    8.              var data = google.visualization.arrayToDataTable(json);
    9.              var ac = new google.visualization.ComboChart(document.getElementById('visualization-<?= $i ?>'));
    10.              ac.draw(data, {  
    11.                      width: 170,
    12.                       height: 55
    13.               });
    14.     }
    15. </script>
    16. <div id="visualization-<?= $i ?>" ></div>
    17. Можно ли как то её вынести и подставлятть параметры
    18. типо такого drawVisualization(divID, data)
    19. Но как тогда её вызывать с такими параметрами, google.setOnLoadCallback(drawVisualization);
    Вдруг кому пригодиться, функцию просто выносим за приделы цикла, а в цикле пишем
    Код (Text):
    1.  
    2. <script type="text/javascript">                                    
    3.      google.setOnLoadCallback(function(){
    4.           drawVisualization( <?= $i; ?>, '<?= $data; ?>')
    5.      });
    6. </script>
    Добавлено спустя 53 секунды:
    Т.е. вызываем её анонимно, можно ещё через глобальные переменные, но это вариант не очень.
     
  15. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    а зачем?
     
  16. vayas

    vayas Активный пользователь

    С нами с:
    13 дек 2012
    Сообщения:
    167
    Симпатии:
    9
    Адрес:
    Пермь
    Что зачем?
     
  17. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    зачем ты так делаешь?

    Добавлено спустя 4 минуты 1 секунду:
    зачем ты всё это делаешь вообще? =) пишешь десять раз одно и то же
    Код (Text):
    1. <script type="text/javascript">                                    
    2.      google.setOnLoadCallback(function(){
    3.           drawVisualization( <?= $i; ?>, '<?= $data; ?>')
    4.      });
    5. </script>
    в цикле!!!
    вызываешь анонимно... зачем это всё?

    почему ты не выкинешь через тот же json_encode массив чисел, по которому потом в цикле на странице пройдёшься на стороне клиента и вызовешь всё это уже в самой функе drawVisualization() в которую прямо можно записать все параметры и как я выше сказал,и дёрнуть её один раз через твой этот setOnLoadCallback()?

    зачем такой огород?
     
  18. vayas

    vayas Активный пользователь

    С нами с:
    13 дек 2012
    Сообщения:
    167
    Симпатии:
    9
    Адрес:
    Пермь
    Именно внутри функции ты предлагаешь организовать цикл, или я не правильно понял тебя?
    Т.е. у нас приедут с сервера все данные в json формате вызываем 1 раз drawVisualization() и уже внутри циклом разбираем данные. Только это получается на стороне клиента будет.
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    да! =) и скормить в него массив, который ты вывалишь примерно так:
    Код (Text):
    1.  
    2. <script type="text/javascript">
    3. var array = <?php echo json_encode($array);?>;
    и дальше цикл.

    Добавлено спустя 30 секунд:
    да прям на страницу фигач

    Добавлено спустя 1 минуту 2 секунды:
    оно и так и так там. ты подготовь все данные как сейчас на стороне сервера, только не в цикле выкладвыай, а скопи в другой массив и его уже в функцию впрысни =)
     
  20. vayas

    vayas Активный пользователь

    С нами с:
    13 дек 2012
    Сообщения:
    167
    Симпатии:
    9
    Адрес:
    Пермь
    Да, что то я об этом не думал. Ладно сейчас по смотрю как переделать.