Как оптимизировать MySQL Views - PullRequest
2 голосов
/ 20 июня 2009

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

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

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

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   

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

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

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

Ответы [ 2 ]

4 голосов
/ 24 июня 2009

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

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

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) 
0 голосов
/ 20 июня 2009

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

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

from orders as ord force index for join (yourindex)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...