Скорость выполение при PDO::ATTR_EMULATE_PREPARES false

membrilius

Новичок
Добрый день!

На большом количестве запросов к БД (MySQL) столкнулся с проблемой через чур медленной работы скрипта.

Опытным путем определил что все дело в выключенном PDO::ATTR_EMULATE_PREPARES.

Для сравнения с включенным режимом эмуляции, скрипт отрабатывает за 0.6-0.5 сек.
Если эмуляцию выключить скрипт отрабатывает за 1.3-1.1 сек.
Собственно разница больше чем в 2 раза.

Кто не знает, смысл режима эмуляции в том, где подготавливаются запросы к БД. Включено - PDO, Выключено - СУБД. В моём случае это MySQL.

На самом деле сервер настроен правильно, непонятно, что MySQL там такого с запросов колдует.

Кто-нибудь замечал разницу?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Кто не знает, смысл режима эмуляции в том, где подготавливаются запросы к БД. Включено - PDO, Выключено - СУБД. В моём случае это MySQL.
На самом деле сервер настроен правильно, непонятно, что MySQL там такого с запросов колдует.
Ну, подготовить запрос на сервере всяко медленее, чем это сделать склейкой и эскейпингом строк на на клиенте, так что это нормально. Это имеет смысл в случае большого количества одинаковых запросов с разными данными в подстановке в пределах одного соединения, что в условиях пхп встречается чуть чаще, чем никогда.
А вот кстати данные из какого-нибудь дампа может оказатся выгружать быстрее с выключенной эмуляцией.
 

membrilius

Новичок
Эмыляция OFF имеет смысл если нужны пресловутые Limit. MySQL понимает, что это конструкция Limit и правильно обрабатывает плейсехолдеры, в PDO обрамляет кавычками все что не попадя.

Я всеровно не понимаю такую большую разницу во времени выполнения. В коннечном итоге PDO и MySQL должны обработать плейсхолдеры и получить что-то одинаковое. Но МуСкулу для этого требуется в 2 раза больше времени. Врятли дело только в определении типа значения плейсхолдера.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Я всеровно не понимаю такую большую разницу во времени выполнения. В коннечном итоге PDO и MySQL должны обработать плейсхолдеры и получить что-то одинаковое. Но МуСкулу для этого требуется в 2 раза больше времени. Врятли дело только в определении типа значения плейсхолдера.
Потому что мускул не просто "обрабатывает плейсхолдеры". Подготовленные запросы вообще механизм более сложный, чем просто эскейпинг данных. Честный поготовленный запрос на стороне сервера - это уже построенный план запроса, оптимизации по индексам, и т.п., что при большом количестве одинаковых запросов по структуре запросов, но с разными данными, дает оч. большой прирост в эффективности.
 

membrilius

Новичок
При включенной эмуляции, MySQL так же выстраивает и оптимизирует индексы и т.д. этим же не занимается PDO, он не знает ничего об индексах.
Не важно включена эмуляция или нет, в конечном итоге мы получаем одно и тоже - результат запроса. Только на выполнение действий в одном случае уходит в 2 раза больше времени.
 

Фанат

oncle terrible
Команда форума
membrilius
База у тебя где? В соседнем городе, небось?
Вот и объяснение.
 

membrilius

Новичок
Фанат

В соседней папке.
А какая разница в подготовки запроса и местоположением базы? Разве так и так кол-во запросов в БД не одинаково?
 

Фанат

oncle terrible
Команда форума
С какого это перепугу одинаково?
попробуй посчитать, сколько запросов с эмуляцией
PHP:
$db->query()
и без
PHP:
$db->prepare()
$stm->execute()
про базу с этого места поподробнее. Под папкой - это что имеется в виду? Игрушечная база данных эскулайт?
 
Последнее редактирование:

membrilius

Новичок
Фанат

К сожалению я в данный момент не могу проверить кол-во обращений к БД при:

PHP:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->prepare()
$stm->execute()
и

PHP:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$db->prepare()
$stm->execute()
....

На счет местоположения БД, я чую подвох...
Под папкой имеется ввиду директории /var/lib/mysql/, /usr/lib/mysql/, /usr/bin/mysql/ ... не думаю что имеет смысл описывать зачем и почему так.
Вообщем она не удаленная, а сервер на той же машине запущен.
 

Фанат

oncle terrible
Команда форума
Проверять не надо. Из самой сути эмуляции следует что обращений в два раза меньше.
А вот почему у тебя обращения к базе занимают столько времени на локальной машине - надо разбираться.

В любом случае, твоя ситуация не типичная, а исключительная. Ни у кого таких гигантских задержек нет.

По поводу лимита же - ну добавь уже проверку на тип значения!
Делов на 15 минут.
Ты же всё равно руками всё биндишь, насколько я помню.
Ну вот и проверяй сначала тип, и подставляй INT для интов.
И всё - проблема решена!
 

membrilius

Новичок
Если бы руками... У меня обертка и типизация плейсхолдеров в ней абсолютно не по феншую.

Ладно, на самом деле у меня сейчас поставлен свеженький MySQL 5.6... надо будет проверить на 5.5, а то эти люди из Оракала опять так всё оптимизировали, что в 3 раза медленнее стало работать.
 

Фанат

oncle terrible
Команда форума
У меня обертка
О НЕЙ И РЕЧЬ.

Раз ты все равно делаешь биндинг сам, а не отдаешь ПДО, то добавить в него проверку типа - как два байта переслать.

плейсхолдеры тебя никто обрабатывать не заставляет.
Всё что нужно - это работа с подставляемыми значениями. Кода - 5 строк.
Ты дольше здесь жалуешься, чем у тебя бы заняло времени код написать.
 

Фанат

oncle terrible
Команда форума
А со скоростью не разобрался?
На какой-нибудь другой машине не пробовал?

что у тебя там за запросы такие, кстати, что аж полсекунды выполняются?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Ну, подготовить запрос на сервере всяко медленее, чем это сделать склейкой и эскейпингом строк на на клиенте, так что это нормально.
предлагаю проверить эту эмпирическую чушь экспериментально с какими-нибудь нормальными СУБД - Postgres, например
я проверял, для меня - без неожиданностей, ибо, как сказал кто-то из авторов, mysql - это куча говнокода
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
предлагаю проверить эту эмпирическую чушь экспериментально с какими-нибудь нормальными СУБД - Postgres, например
Про Postgres, кстати, вот тут некто Котеров пишет, что не стоит использовать prepare / execute, кроме случаев выполнения нескольких запросов с разными параметрами.
Котерова дополню: для одного запроса больше смысла в pg_query_params(), в ём план будет строиться с учётом реально подставляемых значений, но при этом значения пойдут отдельно от запроса, как и в случае pg_prepare() / pg_execute().
 

флоппик

promotor fidei
Команда форума
Партнер клуба
т.е. моя эмпирическая чушь не такая уж чушь, угу.
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
т.е. моя эмпирическая чушь не такая уж чушь, угу.
Чушь, конечно. План-то строится и для запроса с параметрами, и для запроса без, вся проблема в том, что для запроса с параметрами может быть построен неоптимальный, и будет тормозить выполнение, то есть стадия execute в prepare / execute.
 
Сверху