Ответ Гилиана великолепен, но я просто хотел добавить, что иногда бывают редкие исключения из лучших практик, и вы можете протестировать свою среду в обоих случаях, чтобы увидеть, что будет работать лучше.
В одном случае я обнаружил, что query
работал быстрее для моих целей, потому что я выполнял массовую передачу доверенных данных из коробки Ubuntu Linux с PHP7 с плохо поддерживаемым драйвером Microsoft ODBC для MS SQL Server .
Я пришел к этому вопросу, потому что у меня был длинный скрипт для ETL , который я пытался выжать из-за скорости.Мне показалось интуитивно понятным, что query
может быть быстрее, чем prepare
& execute
, потому что он вызывает только одну функцию вместо двух.Операция привязки параметров обеспечивает превосходную защиту, но она может быть дорогостоящей и, возможно, ее можно избежать, если в этом нет необходимости.
Учитывая пару редких условий :
ЕслиВы не можете повторно использовать подготовленный оператор, потому что он не поддерживается драйвером Microsoft ODBC .
Если вы не беспокоитесь о дезинфекции ввода и допустимо простое экранирование,Это может быть связано с тем, что привязка определенных типов данных не поддерживается драйвером Microsoft ODBC .
PDO::lastInsertId
не поддерживаетсядрайвер Microsoft ODBC.
Вот метод, который я использовал для тестирования своей среды, и, надеюсь, вы можете скопировать его или что-нибудь получше:
Для начала ямы создали базовую таблицу в Microsoft SQL Server
CREATE TABLE performancetest (
sid INT IDENTITY PRIMARY KEY,
id INT,
val VARCHAR(100)
);
А теперь базовый синхронизированный тест для метрик производительности.
$logs = [];
$test = function (String $type, Int $count = 3000) use ($pdo, &$logs) {
$start = microtime(true);
$i = 0;
while ($i < $count) {
$sql = "INSERT INTO performancetest (id, val) OUTPUT INSERTED.sid VALUES ($i,'value $i')";
if ($type === 'query') {
$smt = $pdo->query($sql);
} else {
$smt = $pdo->prepare($sql);
$smt ->execute();
}
$sid = $smt->fetch(PDO::FETCH_ASSOC)['sid'];
$i++;
}
$total = (microtime(true) - $start);
$logs[$type] []= $total;
echo "$total $type\n";
};
$trials = 15;
$i = 0;
while ($i < $trials) {
if (random_int(0,1) === 0) {
$test('query');
} else {
$test('prepare');
}
$i++;
}
foreach ($logs as $type => $log) {
$total = 0;
foreach ($log as $record) {
$total += $record;
}
$count = count($log);
echo "($count) $type Average: ".$total/$count.PHP_EOL;
}
Я играл с несколькими различными пробными версиями и подсчетами в моем конкретноми на 20-30% быстрее получают результаты с query
, чем prepare
/ execute
5.8128969669342 prepare
5.8688418865204 prepare
4.2948560714722 query
4.9533629417419
5.9051351547241 подготовить
4.332102060318 запрос
5.9672858715057 подготовить
5.0667371749878 запрос
3.8260300159454 запрос
4.0791549682617 запрос
4.3775160312653 запрос
3.6910600662231 запрос
5.2708210945129 подготовка
6.2671611309052 подготовка
7.3791449069977 подготовка
(7) подготовка Среднее: 6.0673267160143
(8) запрос средняя: 4.3276024162769
Я c любопытныйчтобы увидеть, как этот тест сравнивается в других средах, таких как MySQL.