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分钟才能完成。其他一切都在一分钟之内。