mysql卡在内部连接查询中

Posted

技术标签:

【中文标题】mysql卡在内部连接查询中【英文标题】:mysql stuck in inner join query 【发布时间】:2016-12-28 15:26:54 【问题描述】:

我有一个包含大约 200 个表的 mysql 数据库,每个表有大约 40,000 个条目。 我正在尝试内部连接,但在 xamp 环境中,大约需要 4hrs... 以及在云上它只是在 10 分钟后给出错误 500。 这是查询

SELECT DISTINCT od.io_id, od.io_date, sm.style_code, cm.short_name, od.cust_po, od.mepl_no, od.season, btm.cat_art_no, odd.rev_del_date, od.total_qty, od.shipping_qty, um.short_name, od.order_value_fc, od.order_value_inr, odd.ex_factory_date, od.repeat_order, ot.order_type_name, od.agent_commission AS return_bonus, cm.bonus_discount, cm.other_discount, od.status, il.short_name AS terms, delm.delivery_mode_name, c.short_name AS cur
FROM orderdetails od
INNER JOIN bomtrimqty btm ON od.style_id = btm.style_id
INNER JOIN orderdeliverydetails odd ON od.io_no = odd.io_no
INNER JOIN ordertype ot ON od.order_type_id = ot.order_type_id
INNER JOIN stylemaster sm ON od.style_id = sm.style_id
INNER JOIN customermaster cm ON od.customer = cm.customer_id
INNER JOIN unitmaster um ON um.unit_id = sm.unit_id
INNER JOIN deliverymodelist delm ON delm.delivery_mode_id = odd.rev_del_mode
INNER JOIN incotermlist il ON il.inco_term_id = od.order_type_id
INNER JOIN currency c ON od.fc_unit = c.currency_id
ORDER BY od.io_id DESC

我试过了

GROUP BY od.io_id DESC
LIMIT 10

但没有运气.. mysql 没有给出任何错误.. 请帮帮我

提前谢谢!

【问题讨论】:

你加入的所有列都有索引吗?还有orderdetails.io_id上的索引? 同意@Barmar - 这可能是与某些列缺少索引有关的问题。 由于脚本时间限制,我建议 500 错误...检查 php error_reporting 设置以获取更多信息.. 除了正确的索引:我没有看到任何限制您检索内容的因素。使用多个“WHERE”子句,并将结果限制在您实际使用的那些。 'GROUP BY' 不同,因为它仍然需要所有数据。 @AashishPande 这将是你的问题。对于每个连接,它都必须进行全表扫描。这意味着它必须扫描40,000^10 行。 【参考方案1】:

首先你可以添加一些索引:

ALTER TABLE orderdetails ADD INDEX abc (customer, style_id, io_no, order_type_id, fc_unit);
ALTER TABLE bomtrimqty ADD INDEX abc (style_id);
ALTER TABLE orderdeliverydetails ADD INDEX abc (io_no, rev_del_mode);
ALTER TABLE ordertype ADD INDEX abc (order_type_id);
ALTER TABLE stylemaster ADD INDEX abc (style_id, unit_id);
ALTER TABLE customermaster ADD INDEX abc (customer_id);
ALTER TABLE unitmaster ADD INDEX abc (unit_id);
ALTER TABLE deliverymodelist ADD INDEX abc (delivery_mode_id);
ALTER TABLE incotermlist ADD INDEX abc (inco_term_id);
ALTER TABLE currency ADD INDEX abc (currency_id);

然后您可以更改加入顺序:

SELECT 
DISTINCT 
  od.io_id, od.io_date, sm.style_code, cm.short_name, od.cust_po, od.mepl_no, od.season, btm.cat_art_no, odd.rev_del_date, od.total_qty, od.shipping_qty, 
  um.short_name, od.order_value_fc, od.order_value_inr, odd.ex_factory_date, od.repeat_order, ot.order_type_name, od.agent_commission AS return_bonus, 
  cm.bonus_discount, cm.other_discount, od.status, il.short_name AS terms, delm.delivery_mode_name, c.short_name AS cur
FROM orderdetails od
INNER JOIN customermaster cm ON od.customer = cm.customer_id
INNER JOIN stylemaster sm ON od.style_id = sm.style_id
INNER JOIN unitmaster um ON um.unit_id = sm.unit_id
INNER JOIN bomtrimqty btm ON od.style_id = btm.style_id
INNER JOIN orderdeliverydetails odd ON od.io_no = odd.io_no
INNER JOIN ordertype ot ON od.order_type_id = ot.order_type_id
INNER JOIN deliverymodelist delm ON delm.delivery_mode_id = odd.rev_del_mode
INNER JOIN incotermlist il ON il.inco_term_id = od.order_type_id
INNER JOIN currency c ON od.fc_unit = c.currency_id
ORDER BY od.io_id DESC
;

你现在的表现如何?

【讨论】:

while ALTER --- '错误代码:1072。表中不存在键列'rev_del_mode'' 对不起... ALTER 工作正常... 但加入订单查询需要 5 小时 EXPLAIN SELECT yourQuery 的输出是什么? [link] goo.gl/flPlbA 用于输出 EXPLAIN SELECT查询结果有什么建议吗?【参考方案2】:

请尝试使用子查询而不是许多 JOIN,并为您将在 WHERE 条件下使用的那些字段保留索引,此策略将起作用。

【讨论】:

以上是关于mysql卡在内部连接查询中的主要内容,如果未能解决你的问题,请参考以下文章

在内部连接中排序

在内部联接中重用 mysql 子查询

如何在内部连接表上强制索引?

mysql 自连接查询

MySQL数据操作与查询(第七章 下)

mysql-面试-外连接查询