为什么 MySQL 扫描更新但查找 select
Why does MySQL do a scan for update but lookup for select
我有这两个问题。如您所见,它在 TabRedemption 中查找 orderItemID。 select 只需几分之一秒,而更新大约需要 30 秒。
为什么 MySQL 在更新中使用全索引扫描,我该如何阻止它。它已经有一个外键约束和索引。
select RedemptionID from TabRedemption where orderItemID in
(SELECT OrderItemID FROM TabOrderDetails WHERE OrderId = 4559775);
UPDATE TabRedemption SET active = 1 where orderItemID in
(SELECT OrderItemID FROM TabOrderDetails WHERE OrderId = 4559775);
奇怪的是,如果我手动解析子查询会很快。
UPDATE TabRedemption SET active = 1 where orderItemID in (2579027);
我注意到如果我使用 update with join
查询速度很快,但我不想这样做,因为 h2database 不支持它。
附带说明 MS SQLServer 做得很好。
最佳解决方法:
UPDATE TabRedemption
JOIN TabOrderDetails USING(orderItemID)
SET TabRedemption.active = 1
WHERE TabOrderDetails.OrderId = 4559775;
(或类似的东西)
答案是SELECT
和UPDATE
使用不同的解析器。解决方法是向 UPDATE 添加第二个 table,因为它将使用 SELECT 解析器。
Oracle 在 MySQL 5.7 中解决了解析器的差异。
请记住,模式 "IN ( SELECT ... )" 在许多情况下优化不佳(尽管显然不是你的情况)。
我有这两个问题。如您所见,它在 TabRedemption 中查找 orderItemID。 select 只需几分之一秒,而更新大约需要 30 秒。
为什么 MySQL 在更新中使用全索引扫描,我该如何阻止它。它已经有一个外键约束和索引。
select RedemptionID from TabRedemption where orderItemID in
(SELECT OrderItemID FROM TabOrderDetails WHERE OrderId = 4559775);
UPDATE TabRedemption SET active = 1 where orderItemID in
(SELECT OrderItemID FROM TabOrderDetails WHERE OrderId = 4559775);
奇怪的是,如果我手动解析子查询会很快。
UPDATE TabRedemption SET active = 1 where orderItemID in (2579027);
我注意到如果我使用 update with join
查询速度很快,但我不想这样做,因为 h2database 不支持它。
附带说明 MS SQLServer 做得很好。
最佳解决方法:
UPDATE TabRedemption
JOIN TabOrderDetails USING(orderItemID)
SET TabRedemption.active = 1
WHERE TabOrderDetails.OrderId = 4559775;
(或类似的东西)
答案是SELECT
和UPDATE
使用不同的解析器。解决方法是向 UPDATE 添加第二个 table,因为它将使用 SELECT 解析器。
Oracle 在 MySQL 5.7 中解决了解析器的差异。
请记住,模式 "IN ( SELECT ... )" 在许多情况下优化不佳(尽管显然不是你的情况)。