MySQL - медленный запрос при сохранении вида - PullRequest
0 голосов
/ 16 сентября 2018

В MySQL у меня есть простое соединение между 2 таблицами.Что-то вроде

select a.id, SUM(b.qty) from a inner join b on a.id=b.id
where a.id=12345
group by a.id

Он работает нормально как запрос.Но когда я держу запрос

select a.id, SUM(b.qty) from a inner join b on a.id=b.id
group by a.id

в представлении, называемом view_ab, представление занимает огромное количество времени, когда я запускаю следующий запрос в представлении.

select * from view_ab where id = 12345

Обаэти таблицы большие таблицы.Невозможно выяснить причину такого падения производительности.Пожалуйста, помогите решить эту проблему производительности

РЕДАКТИРОВАТЬ: Это представление SQL

CREATE VIEW view_ab AS SELECT 
r.drid            AS drid,
SUM(s.return_qty) AS return_qty
FROM tbl_deliveryroute r INNER JOIN tbl_deliveryroute_sku s ON r.drid = 
s.drid GROUP BY r.drid;

Это запрос

SELECT 
r.drid            AS drid,
SUM(s.return_qty) AS return_qty
FROM tbl_deliveryroute r INNER JOIN tbl_deliveryroute_sku s ON r.drid = 
s.drid WHERE r.drid=12718651
GROUP BY r.drid;

Это запрос на VIEW

SELECT * FROM view_ab WHERE drid=12718651;

План выполнения представления

EXPLAIN EXTENDED SELECT * FROM view_ab WHERE drid=12718651;

id select_type таблицы разделов тип возможных_ключей ключ key_len ref строки, отфильтрованные Extra

1 PRIMARY (NULL) ref 4 const 10 100.00 (NULL)

2 ПРОИЗВОДНЫХ s (NULL) ВСЕ idx_tbl_deliverroute_sku_drid (NULL) (NULL) (NULL) 15060913 100,00 ИСПОЛЬЗОВАНИЕ ВРЕМЕНИ;ИСПОЛЬЗОВАНИЕ filesort

2 ПРОИЗВОДИМ r (NULL) eq_ref PRIMARY, FK_tbl_deliveryroute_1 PRIMARY 4 humdemotest.s.drid 1 100.00 ИСПОЛЬЗОВАНИЕ INDEX

EXPLAIN EXTENDED  SELECT 
r.drid            AS drid,
SUM(s.return_qty) AS return_qty
FROM tbl_deliveryroute r INNER JOIN tbl_deliveryroute_sku s ON r.drid = 
s.drid WHERE r.drid=12718651
GROUP BY r.drid;

id select_type таблица разделов тип возможных_ключей ключ key_len ref строки фильтрованы

1 SIMPLE r (NULL) const ПЕРВИЧНЫЙ ПЕРВИЧНЫЙ 4 const 1 100,00 ИНДЕКС ИСПОЛЬЗОВАНИЯ

1 SIMPLE s (NULL) ref idx_tbl_deliverroute_sku_drid idx_tbl_deliverroute_sku_drid 4 const 22,00 *

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Причина, по которой просмотр медленный, прост.Вы выполняете:

SELECT *
FROM view_ab
WHERE drid = 12718651;

То, что вы хотите выполнить:

select a.id, SUM(b.qty)
from a inner join
     b
     on a.id = b.id
where a.id = 12345
group by a.id;

На самом деле выполняется:

select ab.*
from (select a.id, SUM(b.qty)
      from a inner join
           b
           on a.id = b.id
      group by a.id
     ) ab
where ab.id = 12345;

То есть всеАгрегация выполняется в первую очередь. Затем применяется where.Вы хотите, чтобы предикат был выдвинут (MySQL называет это слиянием).Вы можете просмотреть документацию по этому вопросу.

Казалось бы, одним из решений является перефразирование запроса в виде коррелированного подзапроса:

select a.id,
       (select sum(b.qty) from b where b.id = a.id) as qty
from a 
where a.id = 12345;

Увы, подзапросы в select имеют тот же эффект, поэтому это не работает.

Я не знаю решения, использующего представление.Вы можете избежать использования представлений для этого.Конечным решением будет реализация триггера для сохранения обобщенных результатов в другой таблице, что эффективно материализует представление.

0 голосов
/ 16 сентября 2018

Из того, что я вижу, вам даже не нужно объединение, поскольку вы имеете дело с объединением в том же столбце ключа из A-B, ключ уже существует в таблице B, просто запросите группу по этому. Кроме того, у меня будет индекс для вашего DeliveryRoute_SKU в столбце идентификатора маршрута

SELECT 
      s.drid,
      sum( s.return_qty ) Return_Qty
   from
      tbl_DeliveryRoute_Sku s
   where
      s.drID = 12718651
   group by
      s.drID;

Поскольку вы только делаете ключ и сумму, вам даже не нужна другая таблица. Теперь, если вам нужны другие столбцы из первой таблицы ДРУГОГО, чем ключ, тогда да, вам нужно соединение. Вы могли бы даже упростить шаг дальше, поскольку вы запрашиваете только один идентификатор ключа

SELECT 
      sum( s.return_qty ) Return_Qty
   from
      tbl_DeliveryRoute_Sku s
   where
      s.drID = 12718651;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...