【问题标题】:Very long execution time for sql querysql查询的执行时间很长
【发布时间】:2014-01-27 20:03:49
【问题描述】:

我试图以良好的响应时间执行以下 sql 查询,但是当我添加 ORDER BY 语句时,查询在 5 分钟内没有返回任何内容。

SELECT *  
FROM orders co
LEFT JOIN (SELECT * FROM prod_orders) AS pc
ON co.id_order = pc.id_order
LEFT JOIN (SELECT * FROM clients) AS cl
ON co.id_client = cl.id_client
LEFT JOIN (SELECT * FROM clients_address) AS ca
ON co.id_client = ca.id_client
LEFT JOIN (SELECT * FROM clienti_firme) AS cf
ON ca.id_client = cf.id_client
ORDER BY co.id_order 

【问题讨论】:

  • 你有什么理由使用LEFT JOIN而不是JOIN
  • 如果没有所有内部 Select * 语句将无法工作,即将加入客户端作为 c1。我想他们对性能有很大的影响
  • @user2989408 不是特别的原因,但它正在发生同样的事情
  • 你绝对需要从每个表中返回所有列吗?
  • 请发布您的表的索引和查询的解释计划。没有它们,您只会得到一个猜测,这对您没有多大用处。最好得到最好的答案。

标签: mysql sql database-performance


【解决方案1】:

如果 Order By 拖慢了它试试:

SELECT *  
FROM (SELECT * FROM orders ORDER BY id_order) AS co
LEFT JOIN prod_orders AS pc
ON co.id_order = pc.id_order
LEFT JOIN clients AS cl
ON co.id_client = cl.id_client
LEFT JOIN clients_address AS ca
ON co.id_client = ca.id_client
LEFT JOIN clienti_firme AS cf
ON ca.id_client = cf.id_client
ORDER BY co.id_order 

也许所有派生表的执行计划都使它对第一个表(订单)的每一行运行 SELECT *。试试这个:

SELECT *  
FROM orders co
LEFT JOIN prod_orders AS pc
ON co.id_order = pc.id_order
LEFT JOIN clients AS cl
ON co.id_client = cl.id_client
LEFT JOIN clients_address AS ca
ON co.id_client = ca.id_client
LEFT JOIN clienti_firme AS cf
ON ca.id_client = cf.id_client
ORDER BY co.id_order 

【讨论】:

  • 我刚试了,结果是一样的;没有 ORDER BY 语句可以正常工作,但有了它......只是“挂起”
  • 这些表有索引吗?另外,返回多少行?
  • 好建议瑞克。可以将索引添加到:Prod_orders.id_order clients.id_client clients_address.id_client clienti_firme.id_client
  • 抱歉,刚刚了解到 ORDER BY 正在减慢速度。 orders.id_order 是主键吗?
  • @sean yes 是订单表的主键
【解决方案2】:

Sean 提供的查询非常简单......也就是说,我会确保您在所有相应的表上都有以下索引

prod_orders ( id_order )
clients ( id_client )
clients_address ( id_client )
clienti_firme (id_client)

and of course your 
orders ( id_order )

自从您提到 MySQL 以来,我唯一想要做的就是。尝试添加关键字“STRAIGHT_JOIN”...我认为这不会有什么不同,因为你所有的表都是 LEFT-JOIN,但你永远不知道。

SELECT STRAIGHT_JOIN ... rest of query ...

我能想到的唯一可能杀死它的另一件事是某种笛卡尔数据结果。是的,订单应该与单个客户相关联,但如果该客户有多个地址(家庭、工作、备用办公室等,并且我们不知道您的表格关系),并且再次为 clienti_firme(客户关联的多个记录与),你可能会比你预期的更多。

如果您有一个客户的 100 个订单,并且该客户有 3 个地址并与 10 家公司相关联,那么您现在有 100 * 3 * 10 条记录通过您原本预计只有 100 条的记录(现在有 3000 条) .对所有订单、客户等执行此操作,您就会发现它会成为一个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 2018-07-06
    • 2014-07-07
    相关资源
    最近更新 更多