Pergunta

Eu tenho alguns querys usando pontos de vista, e estes correr muito mais lento do que eu esperaria que deu todas as tabelas relevantes são indexados (e não tão grande de qualquer maneira).

Espero que eu possa explicar isso:

As minhas principais olhares consulta como esta (grosseiramente simplificada)

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

calc_order_status é uma vista, definido assim:

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

Ordens (ord) contêm ordens, order_items conter os itens individuais associados a cada ordem e seus preços.

Todas as tabelas estão indexadas corretamente, mas a coisa funciona lentamente e quando eu faço um EXPLICAR I get

  # 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   

Meu palpite é, "Derived2" refere-se à vista. Os itens individuais (ITM) parecem funcionar bem, indexado por fim _ id. O problema parece ser a linha # 4, que indica que o sistema não usa uma chave para a tabela de pedidos (ord). Mas na consulta principal, o ID do pedido já está definido: esquerda se juntar calc_order_status como RUP no (ors.order _ id = ord.id) e ord.id (tanto na consulta principal e dentro da visão) referem-se a chave primária.

em algum lugar

Eu li que o MySQL simpliy faz não vistas otimizar o bem e pode não utilizam chaves sob algumas condições, mesmo quando disponível. Este parece ser um desses casos.

Gostaria muito de receber quaisquer sugestões. Existe uma maneira de forçar o MySQL para perceber "é tudo mais simples do que você pensa, é só usar a chave primária e você vai ficar bem"? Ou são vistas de forma errada de fazer isso em tudo?

Foi útil?

Solução

Se for de todo possível remover essas associações removê-los. Substituindo-os por subquerys irá acelerá-lo muito.

Você também pode tentar executar algo assim para ver se ele tem qualquer diferença de velocidade em tudo.

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) 

Outras dicas

Um índice é útil para encontrar algumas linhas em uma grande mesa, mas quando você consulta cada linha, um índice apenas atrasa as coisas. Então aqui MySQL provavelmente espera estar usando toda a [ordem] mesa, por isso é melhor não usar um índice.

Você pode tentar se seria mais rápido por forçando MySQL para usar um índice:

from orders as ord force index for join (yourindex)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top