php когда его делает laravel ? Беру этот же запрос из clockwork и запускаю в консоли - выполняется в разы быстрее
профилировщик знает
Ты, конечно, попробовал сделать запрос через чистый php pdo?
для начала попробовал сделать DB::select(DB::raw(«…»)) из tinker с этим запросом … и вуаля! запрос выполнился быстро (ну в моем случае 5 сек это быстро :)) Получается что где то тупит построитель запросов? потому, что обложил именно построение запроса и вызов его конструкциями DB::enableQueryLog (); DB::getQueryLog () и получил 19 сек в выводе … ладно пойду копать дальше
Да ты шо! Не РНР виноват, а твой код? Отэта поворот!
дак самое то странное что код то простой … строю запрос через построитель DB::table ()->select() … потом соответвенно извлекаю данные… и вот тут прикол - если я этот же самый $query приведу в sql подставлю ему bindings и выполню его через DB::select ( DB::raw ( $rawQuery ) ) все выполняется быстро … и это при том, что билдер у меня не элокуент а базового класса \Illuminate\Database\Query\Builder … там по идее даже модели не извлекаются (что бы были накладные расходы какие то)
а кол-во переменных попадающих под binding какое? когда большое кол-во племенных в запросе, может тормозить подготовка запроса. также запрос использует индексы? если да, то возможно индексы цифровые, а на вход летят строки или наоборот, потому и тормозит выборка
А как ты его в скуль приводишь?
$query = $this->buildQuery (); // здесь говится выборка накладываются условия, джойны сортировки и тп, возвращает Builder $query = $query->offset ( $this->start )->limit ( $this->limit ); // далее перевожу его в sql и заполняю параметры $rawQuery = str_replace ( array('?'), array('\'%s\''), $query->toSql () ); $rawQuery = vsprintf ( $rawQuery, $query->getBindings () ); // вызываю DB::select ( DB::raw ( $rawQuery ) );// вот этот вызов в 5 раз быстрее!!! чем просто вызов $query->get()… время замерял и через DB::getQuerylog и просто через microtime()
Чел, ты серьёзно пишешь array() в 2023? Или это какое-то тошнотное легаси?
дело не виндексах … я сравниваю запуск одно и того же запроса через Builder->get() и DB::select(rawsql) … время построения билдером самого запроса я замерил - им можно принебречь
А что против array?=))) Он если что быстрей чем []=)
быстрее на 0,0000000001?
копипаст просто из инета
когда в запросе для подготовки ?, ?, ? ... и таких будет 5-10 тыс. то только одна подготовка может занять от 0.5-3 секунда, а когда ты делаешь raw то подготовка не требуется, я проэто
Движок вначале спарсит [] и переведёт его в array() можно конечно по баловаться с замерами самому, если есть сильное желание поищу завтра статей с уже готовыми замерами
я говорю же … замерял время подготовки и в этом случае там всего два ?
Ну может чуть быстрей. Просто сам факт=)))
покажи, если не секрет, вывод toSql() на QueryBuilder
select wc_orders.id from `wc_orders` inner join `order_product` on `order_product`.`order_id` = `wc_orders`.`id` inner join `wc_products` on `order_product`.`product_id` = `wc_products`.`id` where (LOWER(wc_products.primary_name) regexp ? or LOWER(wc_products.permalink) regexp ?) group by `wc_orders`.id, wc_orders.created_at, wc_orders.id, wc_orders.created_at order by wc_orders.created_at desc
А билдер после запроса не гидрирует модели ? В ларке это тоже довольно дорогая операция. Сделай select(id) посмотри по времени. Вообще медленные запросы надо ловить, делать их через raw и модно много выиграть )
ну собственно я этим и занимаюсь 🙂 просто увидел что не просто запрос тормозит а тормозит именно через билер 🙂 … модели билдер не должен извлекать это же базовый билдер а не Eloquent …. или я ошибаюсь?
и вряд ли в моделях дело (в смысле не извлекает он их) поому, что Builder->count() занимает столько же времени сколько Builder->get()
У билдера есть методы типо first, count, get. Поставь измерение таймингов до этой точки и посмотри сколько занимает ) так поймёшь билдер долго собирается или запрос сам) Потом после этого запроса посмотри, гидрирует ли билдер что то и сколько жто займёт времени
проверил билдерские get count first pluck и сырой запрос … билдерские все одиннаковое время и в 3 раза дольше чем сырой (на большой базе разница растет существенно) … дебагбаром посмотрел извлекалилсь ли модели - нет
https://stackoverflow.com/a/56724706 сдаётся мне, ты забыл/перепутал
array_push медленней чем $arr[] = []
Третий бенч пропустил?
в третем он тестирует снова первый на горячий проц 🙂 имхо тест не равноценный
Я тебе говорю найди эти методы в билдере и посмотри до того как запрос пойдёт на базу посмотри сколько времени занимает )
Я тут в кишках лары такую дичь нашёл)) можно предположить что где то строится не самым оптимальным образом что нибудь )
да там дичи хватает
Ну я увидел не просто магию, а debug_backtrqce извлекает трассировку всю, забирает с неё третий элемент массива и после этого на нем строит логику 😁
ну кстати нормальный вариант … я у них его подглядел и гдето себе вкорячил тоже … но не как логику конечно :)) а именно как дебаг :)) … а как логику использовать - конечно дичь
ну что … как я ипредполагал изначально … тупит драйвер PDO 🙁 если запрос приходит с параметрами ? то они биндятся а если без параметров (они под катом все равно биндятся просто биндить нечего) … то запрос выполняется в разы быстрее
и еще fetchAll() там тоже почему-то занимает столько же времени сколько execute() и в случае с биндингом тоже дольше в разы … что вобще странно тк объем данных то одиннаков
Обсуждают сегодня