Pull to refresh

Comments 51

1. А mysqlnd уже есть в репозиторях debian и CentOS?
2. Как с бенчмарками? насколько растет производительность и падает расход ресурсов?
1. В ubuntu есть пакет php5-mysqlnd, про остальные, увы, ничего сказать не могу.

2. Сам не тестировал, есть вот такой тест: usu.li/blog/benchmark-libmysql-vs-mysqlnd/
В целом оверхед в старом драйвере идет только на работу с API libmysql, так что гигантского прироста ожидать не стоит.
сейчас проведу субъективный тест на своей тестовой конструкции — отпишусь
в целом результат такой:

старый драйвер(mysql): 7.36 sec — 100 000 запросов — выборка в 10 строк, нагрузка на cpu: 54% от ядра 3.1GHz (процесс php), ram: 10m
новый драйвер(mysqlnd): 13.3 sec — 100 000 запросов — выборка в 10 строк, нагрузка на cpu: 74% от ядра 3.1GHz (процесс php), ram: 13m

в случае pdo стало хуже — медленне, больше ест cpu и памяти. пробовал на:
php5-mysqlnd (5.4.4-7)
debian: wheezy/sid

запускался код:
$t = microtime(true);
$pdo = new PDO('mysql:host=localhost;dbname=koshka', 'root', 'password');
for ($i=0; $i<100000; $i++){
    $pdo->query("SELECT * FROM koshka_users LIMIT 10;");
}

$t = microtime(true)-$t;
echo $t;
echo "\n";
ubuntu 12.04
Таже выборка…
Старый драйвер 5.9 секунд 100 000 запросов, нагрузка на CPU: 42% от ядра 2,13GHz
Новый драйвер 8.4 секунд 100 000 запросов, нагрузка на CPU: 68% от ядра 2,13GHz
Увидел строку dsn, вспомнил анекдот:

На русской границе:
— Скажи пароль!
— Пароль.
— Проходи.

У меня тоже на тестовой машине такой пароль, ничего страшного, виртуалку не поломают :)
> В случае использования mysqlnd такой скрипт упадет с превышением памяти, когда кол-во данных из базы превысит предел выделения памяти, указанный в скрипте.
Мне кажется, что для случаев, когда надо во что бы то ни стало вывести большое количество записей из базы на stdout (или в файл; логи, например), такой эффект наоборот нежелателен.
Мне несколько раз доводилось как раз работать с сырым mysql resource и прогонять его через while, вместо использования имевшейся в библиотеке проекта функции (array) fetch_all().
Странно, что они поддерживают mysqli_ функции.
->fetchAll в PDO сейчас везде вижу.
Кто-нибудь знает, зачем они добавляют все новые и новые интерфейсы работы с MySQL? Ну я понимаю еще, зачем продолжать поддерживать старый интерфейс mysql (это прямой биндинг к сишной libmysql), когда есть универсальный PDO. Но зачем добавляли mysqli и mysqlnd в ядро?
Я думаю для альтернативности выбора. Все же PDO медленнее работает, чем тот же mysqli. Там, где нужна скорость — и используют последнее.

Плюс mysqli поддерживает функциональные методы.

У PDO конечно свои плюсы. Но возможность выбора — это имхо, тоже хорошо. Подбор инструмента, исходя из задачи важнее, чем использование универсального решения, которое надежно, но имеет оверхед, который критичен может быть для какого-либо проекта.
Оверхед? :)
Да вы что, смеетесь? Где вы найдете такой «проект», который испытывает оверхед от прослойки между mysql-server и логикой бэкенда? Там где делается в районе 50к запросов к БД?
Под достаточной нагрузкой я замечаю даже время потраченное со совершение tcp коннекта к базе. Хотя оно и мало оно создает заметный тормоз при достаточном количестве коннектов, поэтому мы перешли на unix сокет, он имеет меньшие задержки и более высокую производительность.
К сведению на моем проекте, нагрузка не очень велика: между php и mysql около 15000 одновременных соединений в пики нагрузки (говнокода нет, коннекты закрываются нормально).

P.S. оверхед от прослойки вполне может быть ощутим, но его никто не мерял.
P.P.S. если знаете как заметать оверхед на прослойку — подскажите!
Выше вон даже кто-то протестировал. Там, как видно, используются крайне простые запросы на, очевидно, маленьких объемах данных. И как видно, на тех запросах, этот «оверхед» от 60 до 100% (с накидкой). О боже, это же очень много, правда? Особенно учитывая, что в целом на каждый запрос была потрачена одна микросекунда…

И при чем тут коннект, конечно коннект дорогой. И чем больше их уже открыто, тем дороже будет открыть новый. То есть тут у вас с нагрузкой (с увеличением кол-ва одновременных реквестов) росли задержки на каждый реквест. А здесь они будут константыми, и очень маленькими. Думаю в пхп имплементировали mysqlnd скорее потому, что нужен был нативный драйвер, просто нужен, язык ведь уже достаточно mature, ну и судя по php.net, лицензия не грела совсем.

Более того, зачастую (ну по крайней мере везде, где я видел), в нагруженных системах используют кеширование, в итоге базу хитят довольно малое кол-во запросов.
1. У меня росли задержки не только на реквест, а на время соединения с базой — это реально заметно когда у вас много одновременных пользователей, api, кроны и прочее.

2. Кеширование зачастую не позоволяет избавится от всех запросов к базе (хотя и избавляет от 99% запросов с web), поэтому даже ради одного маленького запроса приходится открывать коннект.
Есть части которые не кешируются — api, кроны (их много и они очень активные и тяжелые), фоновые задачи в демонах.
1. ну я об этом и говорил — растут задержки на коннект и соответственно на реквест. т.к. чем больше реквестов — тем больше коннектов, то соответственно чем больше реквестов, тем медленнее совершается коннект. Но в случае с издержками на драйвер — они будут константыми, независимо от кол-ва реквестов, на каждый будет одна и та же задержка, следовательно если они сейчас для вас составляют менее 1%, то и всегда будут.

2. Апи то почему не юзает кеш?

И да, насчет
> около 15000 одновременных соединений в пики нагрузки
предположим, что 25% из них была открыта кронджобами, остальные 11k были открыты процессами php? Учитывая то, что использовались юникс-сокеты — все это крутилось на одной машине?
N серверов php-fpm с локальными mysql между ними сделана репликация. Insert, Update делается по tcp в одну базу (master), select делается из локальных баз по unix socket 15k соединений — сумма по всем серверам.

Когда смотришь на эту сумму и суммарную потерю производительности (пока коннект устанавливается — живет процесс php и ждёт зря память безпольно, так же копятся еще не обработанные коннекты на nginx, и прочее) происходит ощущение что что то не так — переводишь на unix socket и «висящих» соединений становиться меньше, php отрабатывает быстрее, nginx меньше копит на себе соединений, да и вся конструкция может обработать больше запросов.
Разница 2-6 процентов в производительностит mysqli и PDO. В общем, PDO имеет смысл использовать только там, где нужна поддержка различных СУБД. Ну, или если безх именованных параметров жить не можете :)
> Ну, или если безх именованных параметров жить не можете :)
Их как-бы больше используют потому, что с ними гораздо сложней пропустить в запрос не обработанные данные, не от того, что они прикольней, а чтобы снизить вероятность инъекции насколько это возможно.
Не понял, как именнованные параметры снижают вероятность инъекции по сравнению с неименованными.
По сравнению с неименованными (позиционными, порядковыми) никак, а по сравнению с ручным экранированием — еще как :)

Edit: Hint: человеческий фактор
Ручное экранирование предлагаю забыть как страшный сон.
Именованные параметры удобнее, но жертвовать 2-6% производительности на крупном проекте ради них я бы не стал. То есть речь о том, что это единственное более-менее весомое преимущество PDO перед mysqli помимо поддержки нескольких СУБД. Поэтому хоронить mysqli в пользу PDO, как некоторые здесь предлагают, я смысла не вижу.
Ну… а я бы стал. Эти жертвы очень легко нивилируются масштабированием бэкендов (что тоже — довольно легко, и неизбежно на крупных проектах).
Какое именно масштабирование бэкэндов вы имеете в виду? Приведите пример.
Стоит фронтенд, принимает запросы, распределяет их по пулу бекэндов. Вот и масштабирование. Или я в чем-то ошибаюсь, может определения какие-то путаю?
Ок, а как тут поможет PDO?
Итак, вот:
— Именованные параметры удобнее, но жертвовать 2-6% производительности на крупном проекте ради них я бы не стал. То есть речь о том, что это единственное более-менее весомое преимущество PDO перед mysqli помимо поддержки нескольких СУБД. Поэтому хоронить mysqli в пользу PDO, как некоторые здесь предлагают, я смысла не вижу.

— Ну… а я бы стал. Эти жертвы очень легко нивилируются масштабированием бэкендов (что тоже — довольно легко, и неизбежно на крупных проектах).
Здесь я хотел сказать, что именованные параметры это достаточно хорошая фича, которая приносит нормальную упорядоченность (понятность если хотите) в ваш код, по вполне нормальной цене, а также то, что эта цена не так и велика, учитывая то, что на крупном проекте вы вряд ли обойдетесь без разброса бэкенда на несколько серверов и балансировки их загруженности. Да и вообще говоря, 10% от пдо — это довольно незаметно, в итоге то, что вы предлагаете — микрооптимизация.
Я не говорил, что вы не можете это делать и используя mysqli, но все же то, что предлагает пдо довольно полезная фича (не говоря уже об абстрагировании), и она стоит того. И производительность пхп-кода под нагрузкой всегда очень легко увеличить добавлением ресурсов.
Что ж, вашу точку зрения я понял. Вы готовы жертвовать производительностью ради некоторого дополнительного удобства и сферической абстракции, а я — нет.
То есть, обы эти инструмента полезны по-своему и это хорошо.
PDO для mysql мне не подходит — куча лишних танцев с бубном, его возможности мне не нужны и только мешают т.к. пользуюсь своей оберткой. Для нее mysqli куда удобнее.
Хороший вопрос. Я на своих проектах (вы не поверите) еще сижу на mysql_*, руки до PDO не добрались.
Как я понял они не вводили новый интерфейс, а заменили использование libmysql в mysqli и PDO, немного расширив mysqli (то есть полностью оставив совместимость со старым кодом). mysqlnd — это замена libmysql, а не mysql/mysqli/PDO. То есть интерфейсы для PHP-кода остались те же самые, а изменилась логика их работы, теперь они не требуеют libmysql. То ли не хотят разборок с Ораклом, то ли считают, что написали лучше.
Mysqlnd вроде бы появился с PHP 5.3.0, 30 июня 2009 года и уже тогда все блоги про него трубили. В PHP 5.4 это тот же самый опостылевший уже mysqlnd или какой-то другой?
Складывается впечатление, что написан этот драйвер был «для красоты». Мне не известно ни одной критичной задачи, которая бы не могла быть решена в предыдущих драйверах. По поводу производительности — по моему опыту, работает в среднем также как предки.
Теперь его сделали по дефолту. Если раньше надо было устанавливать php5-mysqlnd (для Debian-based), то теперь не надо.
Глупость, AR создаст такой оверхэд что мама не горюй. Тем паче что AR хорошо справляется только с примитивными запросами.
А мне статья понравилась. Не знал о плагинах к mysqlnd.
первая мысль была «не знал круто», а затем так и не пришло в голову, для чего это можно использовать. Получается лишний слой логики для работы с базой, не очень обоснованный.
Насчет репликации, по-моему, очень круто! Не нужно реализовывать велосипед.
Буду ждать продолжение про асинхронные запросы
Что то я вижу увеличение оверхеда при работе с APC, а не уменьшение как рекламируется в первом абзаце, и в комментариях здесь, и в usu.li/blog/benchmark-libmysql-vs-mysqlnd/. Как же так, новый нативный велосипед медленнее старого?
Самый главный вопрос — в mysqlnd поддерживается биндинг параметров в запросе? Только не подстановкой, а именно родной серверный.
Используйте для этого PDO.
Это понятно. Я к тому, что создавать новую библиотеку, наследующее недостатки оригинальной библиотеки — это просто глупо.
Как ни странно, но на практике биндинг параметров не очень-то и нужен, потому что в современных реалиях все равно работа с БД организуется через ORM или другую прослойку, которой ничего не стоит реализовать гарантированный квотинг параметров. А вот биндинга для where id in(?), встречающегося чрезвычайно часто, не предлставляет, насколько я знаю, ни одна из встроенных библиотек.
Ну, я всю свою сознательную жизнь использую биндинг параметров. Поэтому для меня кажется карйне странным что вместо того, что-бы сделать биндинг в библиотеке, используют различные костыли типа экранирования опасного контента в строках.
Биндинг нужен ещё для того, чтобы кешировать результат работы парсера запросов.
К сожалению в PHP это не работает. Не кэшируется.
Каждый новый запрос в php — это новый коннект к базе, и даже pconnect здесь не спасает.
Так что одного из самых главных преимуществ prepared statements нет. Выясняли это здесь — habrahabr.ru/post/137664/#comment_4588719
Sign up to leave a comment.

Articles