Mysql 基于组优化子查询获取最后一个条目
我们的代码中有一个错误,它将错误的值缓存到Mysql 基于组优化子查询获取最后一个条目,mysql,subquery,Mysql,Subquery,我们的代码中有一个错误,它将错误的值缓存到last\u order\u id(预期的\u previous\u order)列。我正确编写的查询可以找到正确的上一个订单id,但是对于我们的数据集来说太慢了 我想将此数据选择到另一个表中,但我无法选择,因为查询时间太长 我在这里用一个较小的数据集设置了一个简单的示例。原始表大约有170k行 在示例中: 原始\u artwork\u id是这些行的分组方式 order_id是当前行的订单id 实际上一个订单是更正后的最后一个订单id expect
last\u order\u id
(预期的\u previous\u order)列。我正确编写的查询可以找到正确的上一个订单id,但是对于我们的数据集来说太慢了
我想将此数据选择到另一个表中,但我无法选择,因为查询时间太长
我在这里用一个较小的数据集设置了一个简单的示例。原始表大约有170k行
在示例中:
- 原始\u artwork\u id是这些行的分组方式李>
- order_id是当前行的订单id
- 实际上一个订单是更正后的最后一个订单id
- expected_previous_order是当前存储的最后一个订单id。这是错误的值,因为它实际上没有引用最后一个订单id
order\u artwork
表中放置一个新条目,并引用原始\u artwork\u id
和最后一个\u order\u id
当前数据集中对上次订单id的引用不正确
我需要更新所有记录以正确指示上一个订单id。
我这样做是试图找到每一件艺术品,并将其与同一原始\u artwork\u id
的上一个条目连接起来。然后我可以从最后一个条目中提取订单id来更新当前条目last\u order\u id
将当前行与具有相同原始\u artwork\u id的当前行之前创建的上一行联接,或将当前行原始\u artwork\u id=上一行id不确定这是否比当前查询快。但无论如何 首先,您需要添加一个新字段
`pos` int DEFAULT 0,
并更新您的基本案例,以便可以进行加入
update `order_artwork` o
SET `original_artwork_id` = `id`
WHERE `original_artwork_id` IS NULL;
您可以使用COALESCE(原始\u artwork\u id,id)
,但不能在这种情况下使用索引
然后根据原始艺术品id
和日期为每个订单分配行编号
update `order_artwork` o
left join (
SELECT o.id,
@rn := if(@order_id = `original_artwork_id`,
@rn + 1,
if(@order_id := `original_artwork_id`, 1, 1)
) as rn
FROM `order_artwork` o
CROSS JOIN (SELECT @id := 0, @order_id := 0, @rn := 0) as var
ORDER BY `original_artwork_id`,
`created`
) b on
o.id = b.id
set
o.pos = b.rn;
最后更新最后一个订单
UPDATE `order_artwork` o
JOIN (
SELECT o1.original_artwork_id,
o2.order_id,
o1.order_id as last_order_id
FROM `order_artwork` o1
LEFT JOIN `order_artwork` o2
ON o1.pos = o2.pos - 1
AND o1.original_artwork_id = o2.`original_artwork_id`
WHERE o2.pos IS NOT NULL
) as b
ON o.original_artwork_id = b.original_artwork_id
AND o.order_id = b.order_id
SET o.last_order_id = b.last_order_id;
我发现创建的时间列不可靠。所以我决定只找到最后一个最高阶的id和相同的原始id
创建具有更正值的表
CREATE TABLE order_artwork_two AS
select
d1.id,
d1.order_id,
max(d2.order_id) last_order_id,
d1.original_artwork_id
from order_artwork d1
left join order_artwork d2
ON d1.original_artwork_id = d2.original_artwork_id
and d1.order_id > d2.order_id
group by d1.original_artwork_id, d1.order_id;
向新表添加索引。否则,更新会太慢
alter table order_artwork_two add primary KEY(id);
更新我们的原始表
update order_artwork d1
left join order_artwork_two d2 on d2.id = d1.id
set d1.last_order_id = d2.last_order_id;
我看不到预期的结果和问题是什么。性能问题应该包括解释分析
和一些关于表大小、索引、当前时间性能、期望时间等的信息。慢
是一个相对术语,我们需要一个实际值进行比较。我不明白你说查询正常,但你说预期的前一个订单的值是错误的。如果我们不知道预期的输出或逻辑,我们如何优化查询。谢谢您的评论。实际上一个订单包含修正值。查询工作正常,但永远不会使用较大的数据集完成。我试图找出一种优化子查询的方法。预期的\u上一个\u顺序仅用于说明缓存的值在表上是错误的。我觉得小提琴很清楚?也许你也很清楚。我不知道逻辑,你也不花时间解释。那么你希望我们做逆向工程来了解你需要什么吗?谢谢你的详细回复。这最终起作用了,但我发现创建的字段对于很多数据都是错误的。因此,我创建了一个备用查询,只查找具有相同原始\u artwork \u id的最后一个订单id。再次感谢。很高兴知道。那么当时有多快?我不确定是否会提高性能。更新的性能大约需要10分钟才能完成。其他一切都在一分钟之内。