Как ускорить запрос PDO

0

У меня есть таблица базы данных продуктов (tabl_products) с более чем 55 миллионами строк (продуктов) и iam с использованием запроса PDO, чтобы отображать каждый prduct из таблицы tabl_products. Итак, вот моя таблица запросов structre и выберите запрос.

id | pr_name | pr_description | pr_qntty | pr_price


$pr_id = (int)$_GET['id'];
$select_pr = $con->prepare("SELECT pr_name, pr_description, pr_price FROM tabl_products WHERE id=:pr_id");
$select_pr->bindParam(":pr_id", $pr_id);
$select_pr->execute();
if(!($select_pr->rowCount()))
{
   include '404.php'; exit();
}
$fetch_pr = $select_pr->fetch(PDO::FETCH_ASSOC);

echo $pr_name = $fetch_pr['pr_name'].'<br/>';
echo $pr_description = $pr_description['pr_description'].'<br/>';
echo $pr_price = $fetch_all['pr_price'];

Вышеуказанный запрос займет от 2 до 3 минут, чтобы отобразить отдельную информацию о продукте.

Итак, как я могу отображать информацию о продукте в течение 5-10 секунд?

(из комментария)

CREATE TABLE IF NOT EXISTS tabl_products (
    id int(11) NOT NULL AUTO_INCREMENT, 
    pr_name varchar(255) NOT NULL, 
    pr_description varchar(255) NOT NULL, 
    pr_qntty varchar(255) NOT NULL, 
    pr_price varchar(255) NOT NULL, 
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Теги:
performance
pdo

2 ответа

2

Я воссоздал аналогичную базу данных с использованием MySQL 5.7.20, заполнил около 55000000 строк фиктивными данными и запросил вот так:

SELECT * FROM stackoverflow_test.tabl_products WHERE id=12345678;

возвращает результат очень быстро на моем (приличном) ПК (показывает 0.000s в MYSQL Workbench).

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

echo $pr_name = $fetch_pr['pr_name'].'<br/>';
echo $pr_description = $pr_description['pr_description'].'<br/>';
echo $pr_price = $fetch_all['pr_price'];

$pr_description следует заменить на $fetch_pr

$fetch_all следует заменить $fetch_pr

Возможно, в вашем php файле есть что-то еще, что делает выполнение настолько медленным. Попробуйте выполнить минимальный файл или используйте MySQL Workbench (или аналогичный инструмент), чтобы убедиться, что это не проблема с http-сервером или php (возможно, запрос выполняется быстро, но выборка выполняется медленно или возникают другие проблемы?).

Особенно с такой большой базой данных вам нужно убедиться, что индексы используются. В MySQL вы можете сделать это, добавив EXPLAIN (https://dev.mysql.com/doc/refman/5.7/en/explain-output.html) перед вашим запросом, то есть:

EXPLAIN SELECT * FROM stackoverflow_test.tabl_products WHERE id=12345678;

затем проанализируйте поля possible_keys и key, которые должны включать имя вашего индекса (PRIMARY). Если MySQL не использует индекс, добавление инструкции USE INDEX ('PRIMARY') (https://dev.mysql.com/doc/refman/5.7/en/index-hints.html) в ваш запрос должно помочь, но вы должен исследовать, почему он не используется по умолчанию.

FYI, когда я добавил IGNORE INDEX ('PRIMARY') чтобы проверить время выполнения запроса без индекса, запрос выполняется примерно на 30 секунд вместо доли секунды.

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

Пользователь Your Common Sense предположил, что даже если индекс используется, он может быть слишком большим, чтобы вписаться в память, поэтому он читается с диска, который медленный. Вы можете проверить размер индекса и сравнить его с доступной памятью и (при необходимости) соответствующим образом настроить параметры памяти MySQL.

  • 0
    Я думаю, ты лаешь не на то дерево. Объяснение не даст вам никакой подсказки. это должна быть статистика innodb и состояние памяти на сервере БД
  • 0
    EXPLAIN расскажет, используются ли индексы для этого конкретного запроса. Если это так, вы можете провести дополнительное расследование, но если это не так, вы можете «побудить» MySQL использовать индексы с помощью USE INDEX (и выяснить, почему индекс не используется по умолчанию). Я знаю, что мой ответ не является полным решением проблема, но это позволяет устранить некоторые из возможных причин
Показать ещё 2 комментария
-1

Поскольку ваш id уникален (первичный ключ), вы можете добавить LIMIT 1. Потому что, в противном случае, даже когда ваш продукт будет найден один раз, PDO будет продолжать искать другие продукты с этим конкретным идентификатором.

Таким образом, ваш запрос будет выглядеть следующим образом:

SELECT pr_name, pr_description, pr_price FROM tabl_products WHERE id=:pr_id LIMIT 1

Попытайтесь рассказать нам, сколько времени потребуется :)

PS: он используется Doctrine ORM, например:

  • 0
    Здравствуйте, почему вы думаете, что это не имеет смысла? Не могли бы вы развиться? Вы пробовали с LIMIT 1 и без него на таблице 55 миллионов объектов? Спасибо
  • 0
    Это не имеет смысла, потому что планировщик запросов MySQL уже делает это внутренне. Он достаточно умен, чтобы знать, что означает UNIQUE или PRIMARY ключ. См. Stackoverflow.com/questions/3848390/…

Ещё вопросы

Сообщество Overcoder
Наверх
Меню