Intereting Posts
Могут ли скрипты PHP продолжать работать, даже если пользователь закрыл браузер? Как получить идентификатор элемента в переменной PHP передача нескольких параметров с помощью $ .ajax по POST в php-функцию PHP: Есть ли функция, которая преобразует строку даты в читаемый человеком формат? session_start () создает новый сеанс при каждой перезагрузке Возвращаемое значение эхо-функции PHP vs echo внутри функции Каков наилучший способ убедиться, что два человека не редактируют одну и ту же строку в моем веб-приложении? Как я могу отображать изображения с фреймворком Codeigniter? Работа сервера PHP Symfony2 неожиданно завершается Искать несколько слов за раз в строке в Mysql php как выполнить программу .exe с помощью php-скрипта PHP-архитектура, а также пошаговые ссылки и пропускная способность Как я могу сопоставить арабские буквы, используя regexp в php Проблема с RSA-шифрованием строки в PHP и передача ее в .NET-службу Преобразование HTML в PDF (не PDF в HTML) с использованием PHP

Запрос PDO против выполнения

Они оба делают одно и то же, только по-другому?

Есть ли какая-либо разница, кроме использования

 $sth = $db->query("SELECT * FROM table"); $result = $sth->fetchAll(); 

а также

 $sth = $db->prepare("SELECT * FROM table"); $sth->execute(); $result = $sth->fetchAll(); 

?

Solutions Collecting From Web of "Запрос PDO против выполнения"

query запускает стандартный SQL- query и требует, чтобы вы правильно удаляли все данные, чтобы избежать SQL-инъекций и других проблем.

execute запускает подготовленный оператор, который позволяет связывать параметры, чтобы избежать необходимости избегать или указывать параметры. execute также будет работать лучше, если вы повторяете запрос несколько раз. Пример подготовленных заявлений:

 $sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'); $sth->bindParam(':calories', $calories); $sth->bindParam(':colour', $colour); $sth->execute(); // $calories or $color do not need to be escaped or quoted since the // data is separated from the query 

Лучшая практика заключается в том, чтобы придерживаться подготовленных заявлений и execute для повышения безопасности .

См. Также: Являются ли подготовленные PDO заявления достаточными для предотвращения SQL-инъекций?

Нет, они не то же самое. Помимо экранирования на стороне клиента, которую он предоставляет, подготовленный оператор компилируется на стороне сервера один раз, а затем может быть передан разные параметры при каждом выполнении. Это означает, что вы можете сделать:

 $sth = $db->prepare("SELECT * FROM table WHERE foo = ?"); $sth->execute(array(1)); $results = $sth->fetchAll(PDO::FETCH_ASSOC); $sth->execute(array(2)); $results = $sth->fetchAll(PDO::FETCH_ASSOC); 

Как правило, они улучшат производительность, хотя и не заметны в небольших масштабах. Подробнее о подготовленных операциях (версия MySQL) .

Ответ Гилайна велик, но я просто хотел добавить, что иногда есть редкие исключения из лучших практик, и вы можете протестировать свою среду, чтобы увидеть, что будет работать лучше всего.

В одном случае я обнаружил, что query работал быстрее для моих целей, потому что я был массовым переносом доверенных данных из ящика Ubuntu Linux с PHP7 с плохо поддерживаемым драйвером Microsoft ODBC для MS SQL Server .

Я пришел к этому вопросу, потому что у меня был длинный сценарий для ETL, который я пытался сжать за скорость. Мне казалось интуитивным, что query может быть быстрее, чем prepare и execute потому что он вызывает только одну функцию вместо двух. Операция привязки параметров обеспечивает отличную защиту, но она может быть дорогостоящей и, возможно, избегать, если она не нужна.

Учитывая пару редких условий :

  1. Если вы не можете повторно использовать подготовленный оператор, потому что он не поддерживается драйвером Microsoft ODBC .

  2. Если вы не беспокоитесь о дезинфекции входных данных, и простое экранирование является приемлемым. Это может быть так, потому что привязка некоторых типов данных не поддерживается драйвером Microsoft ODBC .

  3. 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 подготовить
5.8688418865204 подготовить
4.2948560714722 запрос
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

Мне любопытно посмотреть, как этот тест сравнивается в других средах, таких как MySQL.