Здравствуйте, Мне надо вывести все запросы и время их выполнения на странице. Используется PDO. Есть-ли такие функции в самом PDO? Если нет, то как лучше это сделать? Заранее спасибо.
Кстати просветите меня кто знает. Говорят с PDO можно не обрабатывать параметры запроса вручную экранирую там кавычки обрамляя в кавычки и все такое - PDO все сам сделает, например с помощью $sth->bindValue(...). Правильно я понимаю, он мне строку возьмет в кавычки и заэкранирует все типа спец символы. NULL отобразит правильно, ну согласно драйверу? Правильно? И второй вопрос. Если это не поддерживается СУБД то нихера он не обезопасит мои параметры да? И что тогда делать то? Заранее благодарю.
1. Да. 2. Обезопасит в любом случае, т.к. при отсутствии этого в драйвере, это выполняется средствами PDO. Кроме того, все существующие драйверы для PDO это умеют. Алсо, у меня сделано так: PHP: <?php public function Query($sql) { $state = false; if (isset($this->connection)) { $this->statement = $this->connection->prepare($sql); if (isset($this->statement)) { $args = func_get_args(); array_shift($args); if (func_num_args()>1) { if (is_array($args[0])) { $args = $args[0]; } } $state = $this->statement->execute($args); } if ($state===false) { $error = $this->statement->errorInfo(); $this->setError($error[0].'['.$error[1].']',$error[2]); } } return $state; } ?> соответстно, PHP: <?php $db->query('select * from table where id = ?', $_GET['id']);
Суть в том, что если БД и драйвер умеют нативно препаред стейтментс, то ошибка синтаксиса например, у тебя может выпасть до начала исполнения запроса, в момент подготовки запроса. Алсо, нативные препаред стейтментс могут кешироватся в БД, давая большой прирост на одинаковых запросах подряд с разными данными. Ненативно это будет просто ряд одинаковых запросов подряд.
Вот некоторые говорят что есть некоторый магический кешь подготовленных запросов, который оперирует ими и если его колошматить разными запросами то он не будет себя оправдывать. То есть, если я с помощью prepared statement делаю такие виды запросов: 1. Запрос А 2. Запрос Б 3. Запрос В 4. Запрос Б Это будет круто, потому что если кэшь на 3 последних запроса, то это будет быстрее. А если в этот кэшь будут попадать так запросы: 1. Запрос А 2. Запрос Б 3. Запрос В 4. Запрос Г 5. Запрос А - уже в кеше не найдется и логика запроса пропарсится заново. Ну то что при использовании prepared statement идет два обращения к серверу это и так понятно. А вот будет ли утвержения выше верными это вопрос. На сколько я читал мануалы, то там говориться что будет быстрее только если идут именно два одинаковых и подряд два запроса. Так как на самом деле то? Если я прав, то prepared statement лучше использовать только при апдейте и инсёрте. Врятли будут подряд повторяться одни и те же селекты.
Simpliest то есть кеша, такого как я привёл пример нет? если действительно нет (как на самом деле и предполагается) , да даже если и есть, то надо рассматривать вероятность одинаковых идущих подряд или близко (в случае присутствия кеша) стоящих, что не очень привлекательно. Поэтому, я думаю тут гораздо привлекательнее безопасность, чем скорость. Хотя блин со скоростью опять же, говориться что при этом механизме используется не строковый, а двоичный протокол обмена, который как бы меньше жрёт ресурсов и быстрее, а блин может кто юзал мерял. знает?
Есть куча разных кешей. Кеш запросов, кеш результатов, кеш дисковых чтений и т.д. Более конкретно ты узнаешь в доках Забей. Используй всегда биндинг и не парься.
моя вердикта: использование prepared statement ускоряет работу только в случаях, когда в одном соединении идут одинаковых несколько подряд запросов. Уменьшение приблизительно в полтора раза. Но эти ситуации обычно маловероятны. В остальных случаях, по сравнению mysqli с prepared statement и без него, а также mysqli с prepared statement и просто mysql, почти без разницы на libmysql или mysqlnd (эта увеличивает длительность обработки коррелируя с коэффициентом увеличения количества записей), механизм prepared statement замедляет работу в те же полтора раза. Поэтому я считаю, что со скоростью очень много лажи, а вот с безопасностью тут уже другой вопрос.
Костян И какие запросы ты гонял? [sql]SELECT `item`.* FROM `location_has_address` INNER JOIN `location` ON `location_has_address`.`location_id` = `location`.`location_id` INNER JOIN `location_has_item` ON `location_has_item`.`location_id` = `location`.`location_id` INNER JOIN `item` ON `location_has_item`.`item_id` = `item`.`item_id` WHERE ( `location_has_address`.`address_id` IN ( SELECT `location_has_address`.`address_id` FROM `location_has_address` WHERE (`location_has_address`.`location_has_address_active`) AND (`location_has_address`.`location_id` = '1'))) AND (`location_has_address`.`location_has_address_active`) AND (`location_has_item`.`location_has_item_closed` IS NULL) AND (`location_has_item`.`location_id` <> '1')[/sql]
я гонял обычные [sql]SELECT `id` FROM `users` WHERE `login` = ? AND `email`= ? SELECT `id` FROM `users` WHERE `login` = ? SELECT `id` FROM `users` WHERE `login` = ? AND `email`= ? LIMIT 30 OFFSET 100 SELECT `id` FROM `users` WHERE `login` = ? LIMIT 30 OFFSET 100 INSERT INTO `users` (login, email) VALUES (?, ?)[/sql] такой вот наборчик во всяких комбинациях. Еще я не мерял память и ЦПУ, так что кто хочет....