MySQL连接性能问题或条件
有谁能想出一种更有效的方法来编写这个查询,因为我运行它时它总是超时MySQL连接性能问题或条件,mysql,Mysql,有谁能想出一种更有效的方法来编写这个查询,因为我运行它时它总是超时 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 su
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
如果我删除或条件,它将在.2秒内完成。即使我用orders表而不是subjects表切换最后一个连接,它也会在.1秒内完成
shipout ON shipout.id_invoice = orders.OrderKey
GROUP BY orders.orderkey
但是当我试图同时加入两者时,或者它超时了。下面是解释:
+----+-------------+----------------+--------+-----------------------------------------+----------------------+---------+--------------------------+--------+----------------------------------------------------+
| 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是,但我不确定是否要发货。您可以尝试重写最后一个连接,如下所示:
shipout ON shipout.id_invoice = COALESCE(subjects.SubjectKey, orders.OrderKey)
这样就消除了OR,但将连接相同的行。这仅在subjects.SubjectKey/orders.OrderKey为NULL时有效,如果另一个在创建联接时不为NULL,则很难在不知道确切数据结构的情况下进行判断。您可以尝试像这样重写最后一个联接:
shipout ON shipout.id_invoice = COALESCE(subjects.SubjectKey, orders.OrderKey)
这样就消除了OR,但将连接相同的行。这仅在subjects.SubjectKey/orders.OrderKey为NULL时有效,如果另一个在进行连接时不为NULL,则很难在不知道确切数据结构的情况下进行判断。当前查询的联合重写
还可以通过正确的索引获得性能
查询
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
需要注意的一点是,我不是数据库管理员,因此无法编制索引 桌子
但仍向数据库管理员寻求建议和索引。对当前查询的联合重写
还可以通过正确的索引获得性能
查询
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
需要注意的一点是,我不是数据库管理员,因此无法编制索引 桌子
但仍需向数据库管理员寻求建议和索引。“需要注意的是,我不是数据库管理员,因此无法为表编制索引”向数据库管理员寻求建议和索引。。在解释中看到“使用临时;使用文件排序”和“使用索引;使用联接缓冲区(块嵌套循环)”是个坏消息,需要确定索引。。很可能将OR语句重写为UNION类型的查询也可以通过正确的索引提高性能。为什么需要subjectdetails?它似乎没有被使用?@ewramner你是对的,它不适用于此查询。在上一次查询中,我从该表中选择了一些列,但在删除所选列时忘记删除联接。但是,无论哪种方式,我在删除连接时都会遇到同样的问题“需要注意的是,我不是数据库管理员,所以我不能索引表”,请数据库管理员提供建议和索引。。在解释中看到“使用临时;使用文件排序”和“使用索引;使用联接缓冲区(块嵌套循环)”是个坏消息,需要确定索引。。很可能将OR语句重写为UNION类型的查询也可以通过正确的索引提高性能。为什么需要subjectdetails?它似乎没有被使用?@ewramner你是对的,它不适用于此查询。在上一次查询中,我从该表中选择了一些列,但在删除所选列时忘记删除联接。不管怎样,我都遇到了与join removedUsing COALESCE相同的问题,因为它阻止MySQL在subjects.SubjectKey或orders.OrderKeyGood上使用索引,但如果查询在毫秒内运行,而没有或这仍然可以解决问题。最近解决了一个非常类似的性能问题。我喜欢这个想法,并且可以看到它的应用,但是是的,它不适用于我的特定数据集使用COALESCE不是一个好主意,因为它阻止MySQL在subjects.SubjectKey或orders.OrderKeyGood point上使用索引,如果查询在毫秒内运行而没有或,这仍然可以解决问题。最近解决了一个非常类似的性能问题。我喜欢这个想法,并且可以看到它的应用,但是是的,它不适用于我的特定数据集。这是一个很好的建议。今后我必须记住工会的接线员。这非常有效,只需0.4秒即可查询。只有当您使用两个独立的(索引)列(如
,其中column1=1或column2=1
)时,此技巧才有意义,这些列可以重写为UNION ALL
方法@Brandon其中column1=1或column1=2
在联合所有中重新布线(其中column1=1或column1=2
将(1,2)
中的列重写到中会更有意义。有意义。谢谢你的进一步解释。很好的建议。今后我必须记住工会的接线员。这非常有效,只需0.4秒即可查询。只有当您使用两个独立的(索引)列(如,其中column1=1或column2=1
)时,此技巧才有意义,这些列可以重写为UNION ALL
方法@Brandon其中column1=1或column1=2
在联合所有中重新布线(其中column1=1或column1=2
将(1,2)
中的列重写到中会更有意义。有意义。谢谢你的进一步解释。