Задать вопрос
@emerysh

Почему очень долго выполняеться запрос к БД?

Здравствуйте, есть такая вещь:

$db_host = 'localhost';
  $db_user = 'root';
  $db_password = '';
  $db_name = 'price_sites';
  
  $linkps = mysqli_connect($db_host, $db_user, $db_password, $db_name);
    
  $query = "SELECT * FROM table1 LEFT JOIN table2  USING(item)";
  $result = mysqli_query($linkps, $query);	

  $numrows = mysqli_num_rows($result);

    function DrawTableNames()
    {
      global $numrows;
      for($i=0;$i<numrows;$i++){
      echo '\< td \>'; 
      echo mysqli_result($result,$i,'item');
      echo '\< \/td \>';

      }
    } 
    function DrawTableSites($site)
    {
      global $numrows;
      for($i=0;$i<numrows;$i++){
        echo "\< td \>",mysqli_result($result,$i,$site),"\< \/td \>";
      }
    }


Но открывается страница этого скрипта и скрипт начинает свое выполнение -5-10 мин.

Если этот же запрос сделать в phpmyadmin: (99207 всего, Запрос занял 0.0002 сек.)

То есть запрос выполняется быстро, но куда уходит столько времени? Как его убрать?
Еще нашел немного информации об serialize - можно ли этим убрать сию задержку?
  • Вопрос задан
  • 1618 просмотров
Подписаться 2 Оценить 6 комментариев
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 2
i_d_1
@i_d_1
Программист PHP
зачем функции DrawTableNames и DrawTableSites? где они используюсться? что попадает в циклы for($i=0;$i < numrows;$i++)? может там 1 000 000 000 000 строк?

следующий момент USING(item) item надо пологать есть в обех таблицах. проверьте одинкового ли он типа и размера в обеиз таблицах которые джойните.

и да таблицы диких размеров сторяться исключительно долго. есть вариант как это дело ускорить но незначительно. передавать данные в json. JS на стороне пользователя кушает его и строка за строкой асинзронно формирует табличку в миллиард строк. можно еще отложенную загрузку присобачить с LIMIT тогда все точно будет быстро работать.
Ответ написан
@emerysh Автор вопроса
Решением было переписать все напрочь, сделал "пагинацию", поиск в самом БД, другими словами server-side
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
politon
@politon
HTML5,CSS3,JS,PHP,SQL,API,canvas,animation...
Попробуй для начала определить вообще время подключение к БД
<?php
$start = microtime(true); 
$host = 'localhost'; // адрес сервера 
$database = 'price_sites';
$user = 'root'; 
$password = ''; 
$link = mysqli_connect($host, $user, $password, $database) 
    or die("Ошибка " . mysqli_error($link));

mysqli_close($link);
echo 'Скрипт выполнен за: '.(microtime(true) - $start).' сек.';

к примеру у меня 0.008999938964844 сек.
Ответ написан
FanatPHP
@FanatPHP
Чебуратор тега РНР
> Если этот же запрос сделать в phpmyadmin:

phpmyadmin - убогая погремушка для ламеров. измерять по нему скорость выполнения запроса - это все равно что смотреть время на стоящих часах. Два раза в сутки покажет правильно...

Во-первых, phpmyadmin подставляет limit для твоего запроса, и запрашивает всего 20 строк из твоих 100 тысяч. Попробуй запросить все, и посмотри, сколько времени будет выполняться. Если вообще выполнится.
Во-вторых, даже для запроса с лимитом, 0.0002 -это мало. Результат явно идет из квери кеша. Один раз выполнил, дальше запрос закэшировался, и радостро выдает тупо результат.
В-третьих, как тут уже все сказхали, делать таблицу на сто тыщ строк - это совсем за пределами осмысленности. Кто будет это читать? Даже если делаешь XLS.

В общем, сначала изменить, сколкьо времени выполняется запрос ЦЕЛИКОМ, а потом сократить количество запрашиваемых строк до разумных значений.
Ответ написан
NikitaTratorov
@NikitaTratorov
CTO
В свете Вышесказанного, если не менять логику и Вам необходимо получить все строки например, для вывода в CSV или Excel, сделать приблизительно следующее:
//set_time_limit(120); // может понадобиться увеличить время выполнения
$db_host = 'localhost';
$db_user = 'root';
$db_password = '';
$db_name = 'price_sites';
  
$linkps = mysqli_connect($db_host, $db_user, $db_password, $db_name);

$limit = 1000;
$offset = 0;
// выполняем запрос с подсчетом общего числа результатов
$query = sprintf("SELECT SQL_CALC_FOUND_ROWS * FROM table1 LEFT JOIN table2  USING(item) LIMIT %d,%d", $offset,$limit);
$result = mysqli_query($linkps, $query);	

// получаем общее число результатов
$resultTotal = mysqli_query($linkps, "SELECT FOUND_ROWS() AS total");
$res = mysqli_fetch_assoc($resultTotal);
$numrows = $res['total'];

// идем в цикле по результатам
for ($offset = 0; $offset <= $numrows ; $offset += $limit) {
    // получаем строки из результата
    while ($row = mysqli_fetch_assoc($result)) {
        // Что-нибудь делаем с полученной строкой
        print_r($row);
    }
    //запрашиваем очередную порцию данных
    $query = sprintf("SELECT * FROM table1 LEFT JOIN table2  USING(item) LIMIT %d,%d", $offset,$limit);
    $result = mysqli_query($linkps, $query);	
}

Сразу говорю, что код может не заработать, ибо писал на память.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
IT ATLAS Москва
от 250 000 до 500 000 ₽