При использовании 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;
}