【发布时间】:2021-03-07 12:31:53
【问题描述】:
我有一个表,其中有一列 Sequence 提供表的排序。我正在尝试根据Sequence 将下一行和上一行连接在一起,以便我可以获得上一个和下一个 SKU 值。
表定义如下:
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`
我在Builder 表中为(Sequence, Shipment Number, Pallet Number) 添加了一个索引。
该查询正确计算下一个 SKU,但性能非常糟糕,即使在我的完整数据集的一个子集(50,000 行)上运行也需要几分钟。我不确定是否可以做任何其他事情来提高此查询的性能。
在 MySQL 8.0.20 上运行。
谢谢!
【问题讨论】:
-
提供完整的 CREATE TABLE 脚本(和数据示例,3-5 相邻行)和精确的 MySQL 版本。
-
如果您使用的是 MySQL 8.x,请考虑使用像
LAG()这样的窗口函数。 -
除了
SELECT MIN(Sequence),你也可以使用SELECT Sequence..... ORDER BY..... LIMIT 1 -
@Luuk 感谢您的建议。我尝试使用
ORDER BY、LIMIT运行查询,但看起来性能比MIN实现稍差。 @Barmar 我试图避免使用窗口函数,因为业务要求是在 ANSI sql 中。 -
有
WHERE子句吗?还是你想把整张桌子都扔掉?
标签: mysql performance groupwise-maximum