有人能想到一种更有效的方式编写此查询,因为它在我运行时会不断超时吗?
SELECT
orders.OrderKey,
shipout.primary_subcategory
FROM
orders
INNER JOIN
orderitems ON orderitems.OrderID = orders.OrderID
INNER JOIN
subjects ON subjects.SubjectID = orderitems.SubjectID
INNER JOIN
subjectdetails ON subjectdetails.SubjectID = subjects.SubjectID
INNER JOIN
shipout ON shipout.id_invoice = subjects.SubjectKey
OR shipout.id_invoice = orders.OrderKey
GROUP BY orders.orderkey
如果我删除OR条件,它将在0.2秒内完成。即使我用orders表而不是subjects表切换了最后一个联接,它也会在0.1秒内完成。
shipout ON shipout.id_invoice = orders.OrderKey
GROUP BY orders.orderkey
但是当我尝试同时使用OR将两者同时加入时,它会超时。这是解释:
+----+-------------+----------------+--------+-----------------------------------------+----------------------+---------+--------------------------+--------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------+--------+-----------------------------------------+----------------------+---------+--------------------------+--------+----------------------------------------------------+
| 1 | SIMPLE | shipout | ALL | | | | | 10658 | Using temporary; Using filesort |
| 1 | SIMPLE | subjectdetails | index | PRIMARY | SubjectDetails_ID | 768 | | 455446 | Using index; Using join buffer (Block Nested Loop) |
| 1 | SIMPLE | subjects | eq_ref | PRIMARY,Subjects_SubjectKey | PRIMARY | 4 | subjectdetails.SubjectID | 1 | |
| 1 | SIMPLE | orderitems | ref | OrderItems_OrderID,OrderItems_SubjectID | OrderItems_SubjectID | 5 | subjectdetails.SubjectID | 1 | |
| 1 | SIMPLE | orders | eq_ref | PRIMARY,Orders_OrderKey | PRIMARY | 4 | orderitems.OrderID | 1 | Using where |
+----+-------------+----------------+--------+-----------------------------------------+----------------------+---------+--------------------------+--------+----------------------------------------------------+
要注意的一件事是,我不是数据库管理员,因此无法索引表。看起来似乎是subjectdetails,但是我不确定出货。
答案 0 :(得分:3)
对当前查询进行UNION重写。
正确的索引编制也可能会提高性能。
查询
SELECT
orders.OrderKey,
shipout.primary_subcategory
FROM
orders
INNER JOIN
orderitems ON orderitems.OrderID = orders.OrderID
INNER JOIN
subjects ON subjects.SubjectID = orderitems.SubjectID
INNER JOIN
subjectdetails ON subjectdetails.SubjectID = subjects.SubjectID
INNER JOIN
shipout ON shipout.id_invoice = subjects.SubjectKey
GROUP BY orders.orderkey
UNION ALL
SELECT
orders.OrderKey,
shipout.primary_subcategory
FROM
orders
INNER JOIN
orderitems ON orderitems.OrderID = orders.OrderID
INNER JOIN
subjects ON subjects.SubjectID = orderitems.SubjectID
INNER JOIN
subjectdetails ON subjectdetails.SubjectID = subjects.SubjectID
INNER JOIN
shipout ON shipout.id_invoice = orders.OrderKey
GROUP BY orders.orderkey
要注意的一件事是,我不是数据库管理员,所以无法索引 桌子
但是仍然请数据库管理员提供建议和索引。
答案 1 :(得分:1)
您可以尝试像这样重写最后一个JOIN:
shipout ON shipout.id_invoice = COALESCE(subjects.SubjectKey, orders.OrderKey)
像这样,消除了OR,但连接了相同的行。仅当subject.SubjectKey /orders.OrderKey为NULL时,此方法才有效;如果在创建JOIN时不是,则为NULL,但是在不知道确切数据结构的情况下很难分辨。