Вопрос

У меня есть несколько запросов, использующих представления, и они выполняются намного медленнее, чем я ожидал бы, учитывая, что все соответствующие таблицы проиндексированы (и в любом случае не такие большие).

Я надеюсь, что смогу это объяснить:

Мой основной запрос выглядит следующим образом (сильно упрощенный)

select [stuff] from orders as ord 
left join calc_order_status as ors on (ors.order_id = ord.id)

calc_order_status это представление, определенное таким образом:

create view calc_order_status as
select ord.id AS order_id,
(sum(itm.items * itm.item_price) + ord.delivery_cost) AS total_total
from orders ord 
left join order_items itm on itm.order_id = ord.id
group by ord.id

Заказы (ord) содержат заказы, order_items содержат отдельные товары, связанные с каждым заказом, и их цены.

Все таблицы правильно проиндексированы, НО все работает медленно, и когда я делаю ОБЪЯСНЕНИЕ, я получаю

  # id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra  
  1 1 PRIMARY ord ALL customer_id NULL NULL NULL 1002 Using temporary; Using filesort 
  2 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 1002   
  3 1 PRIMARY cus eq_ref PRIMARY PRIMARY 4 db135147_2.ord.customer_id 1 Using where 
  4 2 DERIVED ord ALL NULL NULL NULL NULL 1002 Using temporary; Using filesort 
  5 2 DERIVED itm ref order_id order_id 4 db135147_2.ord.id 2   

Я предполагаю, что "derived2" относится к представлению.Отдельные элементы (itm), похоже, работают нормально, индексируются по order _ id.Проблема, по-видимому, в строке # 4, которая указывает на то, что система не использует ключ для таблицы заказов (ord).Но в ОСНОВНОМ запросе идентификатор заказа уже определен:слева присоедините calc_order_status к ors on (ors.order _ id = ord.id) и ord.id (как в основном запросе, так и в представлении) ссылаются на первичный ключ.

Я где-то читал, что MySQL simpliy не так хорошо оптимизирует представления и может не использовать ключи при некоторых условиях, даже когда они доступны.Похоже, это один из таких случаев.

Я был бы признателен за любые предложения.Есть ли способ заставить MySQL осознать, что "все проще, чем вы думаете, просто используйте первичный ключ, и все будет в порядке"?Или взгляды - это вообще неправильный способ решения этой проблемы?

Это было полезно?

Решение

Если это вообще возможно, удалите эти соединения, удалите их.Замена их вложенными запросами значительно ускорит процесс.

вы также могли бы попробовать запустить что-то подобное, чтобы посмотреть, есть ли у него вообще какая-либо разница в скорости.

select [stuff] from orders as ord 
left join (
  create view calc_order_status as
  select ord.id AS order_id,
  (sum(itm.items * itm.item_price) + ord.delivery_cost) AS total_total
  from orders ord 
  left join order_items itm on itm.order_id = ord.id
  group by ord.id
) as ors on (ors.order_id = ord.id) 

Другие советы

Индекс полезен для поиска нескольких строк в большой таблице, но когда вы запрашиваете каждую строку, индекс просто замедляет работу.Итак, здесь MySQL, вероятно, ожидает использования всей таблицы [order], поэтому лучше не использовать индекс.

Вы можете попробовать, если это будет быстрее с помощью принуждение MySQL для использования индекса:

from orders as ord force index for join (yourindex)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top