2013-09-22 2 views
1

У меня есть запрос, как это:Mysql - тот же самый запрос гораздо медленнее, в лучшем сервере

SELECT o.id, 
     o.archieve, 
     listingid, 
     orderdate, 
     paymentdate, 
     os.STATUS, 
     o.shippingpreference, 
     s.NAME AS store, 
     c.fullname AS customer, 
     (
      SELECT COUNT(oi.id) 
      FROM orders_inventory oi 
      WHERE orderid = o.id 
     ) AS itemcount, 
     (
      SELECT COUNT(op.orderid) 
      FROM orders_preorder op 
      WHERE op.orderid = o.id 
     ) AS itemcountPre, 
     a.fullname AS salesrep, 
     fOrderProfit(o.id) AS profit, 
     o.packtime, 
     o.trackingnumber, 
     fSentMailToVendor(o.id) AS sentmailtovendors, 
     a2.fullname AS adminname 
FROM orders o 
     LEFT JOIN orders_status os 
       ON os.id = o.statusid 
     LEFT JOIN stores s 
       ON s.id = o.storeid 
     LEFT JOIN customers c 
       ON c.id = o.customerid 
     LEFT JOIN admins a 
       ON a.id = o.salerepresentativeid 
     LEFT JOIN admins a2 
       ON a2.id = o.adminid 
WHERE TRUE AND archieve = '0' 
GROUP BY o.id 
ORDER BY o.id DESC LIMIT 50 

Да, это немного сложнее и, возможно, она должна быть оптимизирована. Но мой вопрос в том, что тот же запрос выполняется на более старом сервере (mysql v5.5) в 0,4 сек, в то время как он работает в 300сек на сервере с двумя процессорами и лучшим оборудованием (mysql v5.6). Есть идеи?


Использование EXPLAIN EXTENDED на обоих серверах дают 8 строк объяснения, но я считаю, что первые строки делают разницы, так что я перечислил только первое сравнение строк:

Старый сервер:

  • select_type: ПЕРВЫЙ
  • таблица: o
  • тип: индекс
  • possible_keys: Null
  • ключ: ПЕРВИЧНЫЙ
  • key_len: 4
  • реф: Нуль
  • строк: 50
  • фильтруют: 102776
  • Дополнительно: Использование где

Новый сервер:

  • SELECT_TYPE: ОСНОВНОЙ
  • стол о
  • типа: ВСЕ
  • possible_keys: PRIMARY, ид, ORDERDATE, CUSTOMERID, StoreID
  • ключ: Null
  • key_len: Null
  • ref: Null
  • Строки: 51664
  • отфильтровано: 100
  • Дополнительно: с использованием; Использование временных; Использование filesort

Примечание. Между прочим, я преобразовал типы таблиц в новый сервер в InnoDB перед использованием EXPLAIN EXTENDED.

+1

Каковы показатели исходных таблиц в обеих базах данных? – unique2

+0

Показатели: o.id, oi.id, os.id, o.statusid, s.id, o.storeid, c.id, o.customerid и a.id. Они одинаковы для обеих баз данных, потому что я скопировал всю базу данных с старого сервера на новый. Я также попытался проанализировать таблицы и т. Д., Но не работал. – user2804844

+0

Вы сравнили объяснение на обоих серверах? – unique2

ответ

0

Я предполагаю, что структуры таблиц одинаковы и у меня есть хорошее представление о том, что это может быть:

Оптимизатор на 5.6 сильно отличается, чем в 5.5. Вы должны запустить этот оператор с помощью EXPLAIN и посмотреть, что дает вам оптимизатор.

Возможно, вам может понадобиться играть с optimizer_switch (включение или выключение настроек), или вы можете добавить USE INDEX в свой оператор, чтобы сообщить оптимизатору, какой путь выбрать.

В качестве альтернативы вы можете просто запустить запрос много раз и «научить» оптимизатору, какой путь принять, но это, безусловно, не гарантируется.

Я надеюсь, что это поможет.

Сложение с новыми данными:

Как ваше объясняющим заявление показывает, попробовать что-то вроде этого:

SELECT o.id, 
     o.archieve, 
     listingid, 
     orderdate, 
     paymentdate, 
     os.STATUS, 
     o.shippingpreference, 
     s.NAME AS store, 
     c.fullname AS customer, 
     (
      SELECT COUNT(oi.id) 
      FROM orders_inventory oi 
      WHERE orderid = o.id 
     ) AS itemcount, 
     (
      SELECT COUNT(op.orderid) 
      FROM orders_preorder op 
      WHERE op.orderid = o.id 
     ) AS itemcountPre, 
     a.fullname AS salesrep, 
     fOrderProfit(o.id) AS profit, 
     o.packtime, 
     o.trackingnumber, 
     fSentMailToVendor(o.id) AS sentmailtovendors, 
     a2.fullname AS adminname 
FROM orders o use index (primary) -- new change here 
     LEFT JOIN orders_status os 
       ON os.id = o.statusid 
     LEFT JOIN stores s 
       ON s.id = o.storeid 
     LEFT JOIN customers c 
       ON c.id = o.customerid 
     LEFT JOIN admins a 
       ON a.id = o.salerepresentativeid 
     LEFT JOIN admins a2 
       ON a2.id = o.adminid 
WHERE TRUE AND archieve = '0' 
GROUP BY o.id 
ORDER BY o.id DESC LIMIT 50 
+0

Сначала структуры таблиц были одинаковыми, позже я заменил новые серверные таблицы на InnoDB. Я также добавил результаты EXPLAIN к вопросу. Выполнение одного и того же запроса много раз не вносило больших изменений. – user2804844

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