MySQL 查询在一台服务器上有效,但在另一台服务器上无效
MySQL query works on one server but not on another
我正在将我们的 MySQL 服务器 (5.7.15) 迁移到一个更强大的专用盒子(5.7.24,data/schema 大约两周前由旧服务器的 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 连接,因为 "Explain Current Statement" 工具告诉我:
是否有设置阻止此查询在新框上执行相同的操作?造成差异的原因是什么?
很高兴提供任何额外的必要信息。谢谢!
当您将 tables 从一台服务器迁移到另一台服务器时,请务必检查几件事:
您确定新服务器上的 table 与旧服务器上的索引相同吗?执行 SHOW CREATE TABLE tbl;
检查。
迁移后每个 table 都做了 OPTIMIZE TABLE tbl;
了吗?您也可以使用 mysqlcheck -o --all-databases
从命令行执行此操作
优化或分析,table 会重新生成一些内部统计信息。这些统计数据帮助 MySQL 的查询规划器在帮助查询时选择索引,因此有时可以避免完全 table 或索引扫描。
(SHOW CREATE TABLE
和 EXPLAIN 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
好的,你没有写代码。但你现在有责任清理它。否则下一个开发者会把矛头指向你。
我正在将我们的 MySQL 服务器 (5.7.15) 迁移到一个更强大的专用盒子(5.7.24,data/schema 大约两周前由旧服务器的 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 连接,因为 "Explain Current Statement" 工具告诉我:
是否有设置阻止此查询在新框上执行相同的操作?造成差异的原因是什么?
很高兴提供任何额外的必要信息。谢谢!
当您将 tables 从一台服务器迁移到另一台服务器时,请务必检查几件事:
您确定新服务器上的 table 与旧服务器上的索引相同吗?执行
SHOW CREATE TABLE tbl;
检查。迁移后每个 table 都做了
OPTIMIZE TABLE tbl;
了吗?您也可以使用mysqlcheck -o --all-databases
从命令行执行此操作
优化或分析,table 会重新生成一些内部统计信息。这些统计数据帮助 MySQL 的查询规划器在帮助查询时选择索引,因此有时可以避免完全 table 或索引扫描。
(SHOW CREATE TABLE
和 EXPLAIN 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
好的,你没有写代码。但你现在有责任清理它。否则下一个开发者会把矛头指向你。