2016-09-23 2 views
1

Я использую Laravel 5.2 с MySQL 5.6.33Laravel 5,2 Eloquent запрос занимает слишком много времени, чтобы «количество»

При проверке запроса DB, применяя dd(DB::getQueryLog());, он возвращается следующим образом:

array:14 [▼ 
    0 => array:3 [▼ 
    "query" => "select count(*) as aggregate from `products` where exists (select * from `agents` where `products`.`agent_id` = `agents`.`id`) and exists (select * from `productlocations` where `productlocations`.`product_id` = `products`.`id` and `town_id` = ?) and exists (select * from `productagents` where `productagents`.`product_id` = `products`.`id` and `product_status_id` = ?)" 
    "bindings" => array:2 [▼ 
     0 => "674" 
     1 => "1" 
    ] 
    "time" => 22286.26 
    ] 

    1 => array:3 [▼ 
    "query" => "select * from `products` where exists (select * from `agents` where `products`.`agent_id` = `agents`.`id`) and exists (select * from `productlocations` where `productlocations`.`product_id` = `products`.`id` and `town_id` = ?) and exists (select * from `productagents` where `productagents`.`product_id` = `products`.`id` and `product_status_id` = ?) order by `id` desc limit 10 offset 0" 
    "bindings" => array:2 [▼ 
     0 => "674" 
     1 => "1" 
    ] 
    "time" => 38.4 
    ] 

    2 => array:3 [▼ 
    "query" => "select * from `agents` where `agents`.`id` in (?)" 
    "bindings" => array:1 [▶] 
    "time" => 0.58 
] 

Как вы можете видеть результат, запрос «count» занял 22286 мс, но тот же запрос данных фильтрации занял всего 38,4 мс. Где мне нужно посмотреть, чтобы ускорить этот запрос? Нужно изменить в БД или Красноречии?

Edit:

explain 
select * from `products` where exists 
    (select * from `agents` where `products`.`agent_id` = `agents`.`id`) 
and exists 
    (select * from `productlocations` where `productlocations`.`product_id` = `products`.`id` and `town_id` = 674) 
and exists 
    (select * from `productagents` where `productagents`.`product_id` = `products`.`id` and `product_status_id` = 1) 
order by `id` desc limit 10 offset 0 

Подписки являются объяснить выходные и моих таблицы индексов enter image description here

+0

Используйте 'объяснить' до каждого запроса к профилю (например, 'объяснить выберите count (*) как совокупность .... '). Проверьте, имеют ли все столбцы одинаковое значение, скорее всего, они будут использовать разные ключи для запроса. Кроме того, если у вас еще нет индексов, было бы неплохо добавить индекс для столбцов, используемых в операторах 'where'. –

+0

Вы можете попробовать, что рекомендует @milz. Я хотел бы поделиться тем, что, когда все это не работает, мы можем изменить структуру БД. Мы должны добавить столбец в таблицу для общего подсчета. Laravel обеспечивает очень хороший короткий код для приращений и декрементов «DB :: table (« products ») -> increment ('totalsales'); '' Таким образом, запрос будет быстрым, когда у вас есть большие данные. – Tarunn

+0

@milz: Я нашел проблему, когда собираюсь обновить свой вопрос с помощью объяснений и проверок индексов. Некорректное соединение с таблицей агентов и таблицей продуктов также имеет столбец agent_id, но она не была проиндексирована. – Sadee

ответ

0

Я нашел ошибку. Колонка agent_id должна быть проиндексирована в products таблице

0

использовать этот запрос для подсчета первичных ключей вместо * будет держать вас быстрее, чем *

select count(products.id) as aggregate from `products` as Products 
INNER JOIN `agents` as Agent ON (Agent.id = Products.agent_id) 
INNER JOIN productlocations as ProductLocations ON (ProductLocations.product_id = Products.id AND Agent .town_id = 674) 
INNER JOIN productagents as ProductAgents ON (ProductAgents.product_id = Products.id AND ProductAgents.product_status_id = "your input status Id") 
+0

'select count (*), поскольку агрегирование из' table' - это то, как используется Laravel 5.2, чтобы получить общее количество строк результатов, самостоятельно. Я не уверен, может/как это изменить на 'count (id_column)' – Sadee

+0

использовать all() или прямой DB :: query() вместо метода EloquentModel-> count() в этой ситуации, если это полезно для пользовательского запроса, то почему go с заявлением по умолчанию для рамки, –

+0

Да, я использую Product :: with (array (....)) -> paginate ($ limit); В результате этого есть индекс «count». Эта задержка находится в этом запросе. – Sadee

Смежные вопросы