Odpowiedź Gileana jest świetna, ale chciałem tylko dodać, że czasami zdarzają się rzadkie wyjątki od najlepszych praktyk i możesz chcieć przetestować swoje środowisko w obie strony, aby zobaczyć, co będzie działać najlepiej.
W jednym przypadku okazało się, że query
działa to szybciej dla moich celów, ponieważ masowo przesyłałem zaufane dane z komputera z systemem Ubuntu Linux z PHP7 ze słabo obsługiwanym sterownikiem Microsoft ODBC dla MS SQL Server .
Dotarłem do tego pytania, ponieważ miałem długo działający skrypt dla ETL, który próbowałem wycisnąć dla szybkości. Wydawało mi się intuicyjne, że query
może być szybsze niż prepare
&, execute
ponieważ wywoływało tylko jedną funkcję zamiast dwóch. Operacja wiązania parametrów zapewnia doskonałą ochronę, ale może być kosztowna i prawdopodobnie można jej uniknąć, jeśli jest niepotrzebna.
Biorąc pod uwagę kilka rzadkich warunków :
Jeśli nie możesz ponownie użyć przygotowanej instrukcji, ponieważ nie jest ona obsługiwana przez sterownik Microsoft ODBC .
Jeśli nie martwisz się o odkażanie danych wejściowych i zwykła ucieczka jest do przyjęcia. Może tak być, ponieważ wiązanie pewnych typów danych nie jest obsługiwane przez sterownik Microsoft ODBC .
PDO::lastInsertId
nie jest obsługiwany przez sterownik Microsoft ODBC.
Oto metoda, której użyłem do przetestowania mojego środowiska i miejmy nadzieję, że możesz ją odtworzyć lub coś lepszego w swoim:
Na początek utworzyłem podstawową tabelę w Microsoft SQL Server
CREATE TABLE performancetest (
sid INT IDENTITY PRIMARY KEY,
id INT,
val VARCHAR(100)
);
A teraz podstawowy test czasowy dla wskaźników wydajności.
$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;
}
Grałem z wieloma różnymi próbami i liczyłem w moim specyficznym środowisku i konsekwentnie uzyskuję od 20-30% szybszych wyników z query
niż prepare
/execute
5,8128969669342 przygotować
5,8688418865204 przygotować
4,2948560714722 zapytanie
4,9533629417419 zapytanie
5,9051351547241 przygotować
4.332102060318 zapytanie
5,9672858715057 przygotować
5.0667371749878 zapytanie
3,8260300159454 zapytania
4,0791549682617 zapytanie
4,3775160312653 zapytanie
3,6910600662231 zapytanie
5,2708210945129 przygotować
6,2671611309052 przygotować
7,3791449069977 przygotowania
(7) przygotowuje Średnia: 6.0673267160143
(8) zapytania Średnia: 4,3276024162769
Jestem ciekawy, jak ten test wypada w porównaniu z innymi środowiskami, takimi jak MySQL.