MySQL查询可在一台服务器上运行,但不能在另一台服务器上

时间:2018-12-11 22:47:52

标签: mysql query-performance data-migration

我正在将我们的MySQL Server(5.7.15)迁移到功能更强大的专用框(5.7.24,大约两周前由mysqldump从旧服务器创建的数据/模式),并且必须重新创建所有服务器设置MySQL转储未保留的文件。我有这个查询(不是我写的):

SELECT * 
FROM   (SELECT t1.job_status, 
               t1.customer_po, 
               t1.customer_name, 
               t1.order_value, 
               t1.code_division, 
               t1.assigned_sales_person, 
               t1.date_assigned, 
               t2.date_order, 
               IF(t1.job_status = 'PENDING', 
               Datediff(Curdate(), t1.date_assigned), 
               Datediff(t2.date_order, t1.date_assigned)) AS days, 
               force4.Code('DV', t1.code_division)        AS code_desc, 
               t2.order_id 
        FROM   customer_po_log AS t1 
               left join orders AS t2 
                      ON t2.po_id = t1.customer_po 
               left join order_item AS t3 
                      ON t3.order_id = t2.order_id 
                         AND t3.code_division = t1.code_division 
        GROUP  BY t1.customer_po) AS u1 
WHERE  u1.job_status = 'PENDING' 
       AND u1.code_division = 'L' 
ORDER  BY u1.days DESC 

在原始服务器上,查询在0.5秒内完成。在新服务器上,它将超出最大查询时间。我非常确定问题是由于“解释当前语句”工具告诉我的,原因是t3连接:

enter image description here enter image description here

是否存在阻止此查询在新框上执行相同设置的设置?造成差异的原因是什么?

很乐意提供任何其他必要的信息。谢谢!

2 个答案:

答案 0 :(得分:1)

将表从一台服务器迁移到另一台服务器时,请务必检查以下几项:

  1. 您确定新服务器上的表具有与旧服务器上相同的索引吗?执行SHOW CREATE TABLE tbl;进行检查。

  2. 迁移每个表后,您是否为每个表完成了OPTIMIZE TABLE tbl;?您也可以使用mysqlcheck -o --all-databases

  3. 从命令行执行此操作

优化或分析表将重新生成一些内部统计信息。这些统计信息可帮助MySQL的查询计划者在查询时选择索引,从而避免了全表扫描或索引扫描。

答案 1 :(得分:1)

(拥有SHOW CREATE TABLEEXPLAIN SELECT...会很有帮助)

如果您没有这些索引,它们可能有助于提高速度(在两台计算机上):

t2:  (po_id, order_id, date_order)  -- with `po_id` first
t3:  (order_id, code_division)  -- in either order

此外,加入t3似乎完全没有用。由于优化器可能不够聪明,无法为您删除它,因此您应该这样做。

并在其中移动WHERE

并摆脱外面的SELECT

啊,在这里:

SELECT  t1.job_status, t1.customer_po, t1.customer_name, t1.order_value,
        t1.code_division, t1.assigned_sales_person, t1.date_assigned,
        t2.date_order,
        Datediff(Curdate(), t1.date_assigned)) AS days,
        force4.Code('DV', t1.code_division) AS code_desc,
        t2.order_id
    FROM  customer_po_log AS t1
    LEFT JOIN  orders AS t2  ON t2.po_id = t1.customer_po
    WHERE  u1.job_status = 'PENDING'
      AND  u1.code_division = 'L'
    ORDER BY  u1.days DESC 

t1:  INDEX(job_status, code_division)  -- in either order
t2:  INDEX(po_id, order_id, date_order)  -- with `po_id` first

好的,您没有编写代码。但是您现在有责任清理它。否则,下一个开发人员将矛头指向