В примере кода есть несколько серьезных ошибок.Чтобы быть более точным.
// $imageIds is an array with 10K keys
$keyCount = count($imageIds);
$keys = implode(', ', array_fill(0, $keyCount, '?'));
$query = "SELECT * FROM images WHERE ImageID IN ({$keys})";
пока что приведенный выше код будет обеспечивать что-то вроде этого ...
SELECT * FROM images WHERE ImageID IN (?, ?, ?, ?, ?, ?,...?, ?, ?, ?)
Там нет цикла для привязки ... Тамдолжен быть небольшой цикл, в котором вы будете привязывать все параметры, передаваемые в MySQL.Вы переходите от prepare
к execute
. Когда правильный обязательный - это, прежде всего, то, что вы хотите.
$stmt = $dbh->prepare($query);
$stmt->execute($imageIds);
// until now, it's been fast. fetch() is the slow part
while ($row = $stmt->fetch()) {
$rows[] = $row;
}
Теперь у меня есть простой логический вопрос по этой частивопрос ...
При использовании SELECT * FROM table WHERE Id IN ( .. )
запросов с более чем 10000 клавиш с использованием PDO с prepare () / execute () производительность снижается на ~ 10 раз больше, чем при выполнениитот же запрос с использованием mysqli с подготовленными операторами или PDO без использования подготовленных операторов.
Не было бы лучше, если бы тот же запрос был переписан так, чтобы вам не нужно было передавать 10000 ключей в качестве параметров?
PDO
и MySQLi
не имеют существенных различий во времени.Плохо написанные запросы делают.Очень сложные хранимые процедуры иногда могут оказаться медленными, если они плохо оптимизированы.
Проверьте, может ли другой запрос получить желаемый результат.Например,
Создать небольшую таблицу с именем test
create table `test` (
`id` int(10) not null,
`desc` varchar(255)
);
insert into `test` (`id`,`desc`) values (1,'a'),(10,'a1'),(11,'a2'),(12,'a3'),(13,'a4'),(14,'a5'),(15,'a6'),(2,'ab'),(20,'ab1'),(21,'ab2'),(22,'ab3'),(23,'ab4'),(24,'ab5'),(25,'ab6');
Выполнить эти простые запросы
select * from `test` where `id` rlike '^1$';
select * from `test` where `id` rlike '^1+';
select * from `test` where `id`=1;
select * from `test` where `id` rlike '^1.$';
select * from `test` where `id` rlike '.2$';
select * from `test` where `id` rlike '^2$';
select * from `test` where `id` rlike '.(2|3)'; // Slower
select * from `test` where `id` IN (12,13,22,23); // Faster
select * from `test` where `id` IN ('12,13,22,23'); // Wrong result
select * from `test` where `id` IN ('12','13','22','23'); // Slower
Последние 4 запроса имеют одинаковый результат вэтот пример.Я думаю, что в большинстве случаев, если вы отметите его на SQLFiddle , вы получите время запроса, соответствующее метке, которой они были присвоены.