Почему определенные типы подготовленных запросов с использованием PDO в PHP и MySQL работают медленно?

При использовании SELECT * FROM table WHERE Id IN (..) запросы с более чем 10000 ключами с использованием PDO с prepare () / execute (), производительность ухудшается примерно в 10 раз больше, чем при выполнении того же запроса с использованием mysqli с подготовленными операторами или PDO без использования подготовленных операторов.

Более странные детали:

  • Более типичные операторы SELECT, в которых нет предложения WHERE Id IN (..) , работают нормально даже с более чем 100 КБ строк. SELECT * FROM table WHERE Id , например, быстро.

  • Ухудшение производительности происходит после завершения подготовки () / execute () - оно полностью находится в PDOStatement :: fetch () или PDOStatement :: fetchAll () . Время выполнения запроса MySQL во всех случаях крошечное - это не случай оптимизации MySQL.

  • Разбиение запроса размером 10 Кбайт на 10 запросов с ключами 1 Кбайт является эффективным.

  • Использование mysql, mysqli с подготовленными операторами или PDO без подготовленных операторов является производительным.

  • PDO с подготовленными операциями занимает ~ 6 секунд в приведенном ниже примере, в то время как другие занимают ~ 0,5 с.

  • Чем больше у вас ключей, тем хуже нелинейно. Попробуйте использовать ключи 100 тыс.

Пример кода:

// $imageIds is an array with 10K keys
$keyCount = count($imageIds);
$keys = implode(', ', array_fill(0, $keyCount, '?'));
$query = "SELECT * FROM images WHERE ImageID IN ({$keys})";
$stmt = $dbh->prepare($query);
$stmt->execute($imageIds);
// until now, it's been fast.  fetch() is the slow part
while ($row = $stmt->fetch()) {
    $rows[] = $row;
}
23
задан Don MacAskill 3 December 2010 в 23:26
поделиться