mysql - 在更好的服务器中,Mysql的查询要慢得多

  显示原文与译文双语对照的内容
0 0

我有一个这样的查询:


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

是的,它有点复杂,也许应该优化。 但我的问题是,在2 秒的服务器上运行相同的查询,而在2 秒内运行的服务器在2 个CPU和更好的硬件( mysql v5.6 ) 。 有什么想法吗?


使用两个服务器上的解释扩展给出了 8行解释,但我认为第一行产生了差异,所以我只列出了第一行比较:

旧服务器:

  • select_type: 主要
  • 表:o
  • 类型:索引
  • possible_keys: 空
  • 关键字:主要
  • key_len: 4
  • 引用:空
  • 行:50
  • 筛选:102776
  • 额外:使用位置

新服务器:

  • select_type: 主要
  • 表:o
  • 类型:全部
  • possible_keys: 主,id,orderdate,customerid,storeid
  • 密钥:空
  • key_len: 空
  • 引用:空
  • 行:51664
  • 筛选:100
  • 额外:使用位置;临时使用;使用 filesort

注意:顺便说一下,在使用解释扩展之前,我将新服务器中的表类型转换为 InnoDB 。

时间: 原作者:

0 0

我假设表结构是相同的,我有一个很好的主意:

5.6上的优化器与 5.5中的版本非常不同。 你应该用解释来运行这个语句,看看优化器给你的是什么。

你可能需要使用 optimizer_switch ( 打开或者关闭设置),或者向语句中添加使用索引来告诉优化器选择哪个路径。

或者,你可以很多次运行查询,并且"教学"可以使用哪个路径,但这确实不能保证。

我希望能帮助你。

添加新数据:

就像解释语句所示,尝试类似这样的内容:


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

原作者:
...