MySQL 自连接 Table Next/Prev 行性能

MySQL Self Join Table Next/Prev Row Performance

我有一个 table,其中有一列 Sequence 为 table 提供排序。我试图根据 Sequence 将下一行和上一行连接在一起,这样我就可以获得上一个和下一个 SKU 值。

table定义如下:

CREATE TABLE `Builder` (
    `Shipment Number` VARCHAR(50) NULL DEFAULT NULL,
    `SKU` VARCHAR(50) NULL DEFAULT NULL,
    `Pallet Number` VARCHAR(50) NULL DEFAULT NULL,
    `Sequence` INT NULL DEFAULT NULL,

    INDEX `Primary Index` (`Shipment Number`, `Pallet Number`, `Sequence`) USING BTREE
)

我的查询目前看起来像这样计算下一行 SKU 值:

SELECT
    B1.`SKU`,
    B1.`Shipment Number`,
    B1.`Pallet Number`,
    B1.`Sequence`,
    B2.`SKU`
FROM Builder B1

LEFT JOIN Builder B2 ON
    B2.`Sequence.` = (
        SELECT MIN(B3.`Sequence.`)
        FROM Builder B3
        WHERE
            B3.`Sequence` > B1.`Sequence` AND
            B3.`Shipment Number` = B1.`Shipment Number` AND
            B3.`Pallet Number` = B1.`Pallet Number`
    ) AND
    B1.`Shipment Number` = B2.`Shipment Number` AND
    B1.`Pallet Number` = B2.`Pallet Number`

我已经为 (Sequence, Shipment Number, Pallet Number) 添加了一个索引到 Builder table。

查询正确计算了下一个 SKU,但性能非常糟糕,即使 运行 在我的完整数据集(50,000 行)的一个子集上也需要几分钟。我不确定是否还有其他方法可以提高此查询性能。

运行 在 MySQL 8.0.20.

谢谢!

使用 LEAD()LAG() 而不是联接。它们就是为此而生。

例如:

select
  *,
  lag(`SKU`) over(partition by `Shipment Number`, `Pallet Number`
                  order by `Sequence`) as prev_sku,
  lead(`SKU`) over(partition by `Shipment Number`, `Pallet Number`
                   order by `Sequence`) as next_sku
from builder

LAG()returns前一行的值,根据指定的条件(partitionordering), 而 LEAD() returns 根据指定条件的下一行的值。

您还可以添加一个可选的第二个参数(默认为 1 的整数)以指示您想要查看多远(行)。