雪花使用 ORDER BY 插入不一致的行为

Posted

技术标签:

【中文标题】雪花使用 ORDER BY 插入不一致的行为【英文标题】:Snowflake INSERT inconsistent behavior using ORDER BY 【发布时间】:2021-11-29 12:10:03 【问题描述】:

我正在尝试以特定(且简单)的顺序将记录插入表中,因为该表有一个 IDENTITY 列(例如 MyTbl (ID INT IDENTITY(1,1), Sale_Date DATE, Product_ID INT, Sales INT )。

查询很简单(这只是一个简化的例子):

INSERT INTO MyTbl (Sale_Date, Product_ID, Sales)
SELECT Sale_Date, Product_ID,COUNT(*) as sales
FROM Fact_tbl
GROUP BY Sale_Date,Product_ID
ORDER BY Sale_Date,Product_ID

预期的行为是,当我选择身份 ID 列的最高值时,我应该会看到最新的 Sale_Date。然而,这种情况并非如此。表中 ID 列的顺序与日期无关。更糟糕的是,如果我重新创建表并一次又一次地运行相同的 INSERT 语句,我每次都会为相同的数据获得不同的插入顺序。 即使我封装查询并将 ORDER BY 放入或取出外壳,我也会遇到这种情况。

我从未在任何其他 SQL 平台中看到过这种行为。这是 Snowflake 中的预期行为吗?

【问题讨论】:

要检查的 SELECT 查询是什么? 这真的是一个简单的检查:SELECT * FROM MyTbl ORDER BY ID DESC LIMIT 10 您的Product_ID 是否有可能被存储为TEXT 而不是NUMERIC 【参考方案1】:

这是预期的。让我解释一下原因:

AUTOINCREMENT 和 IDENTITY 是同义词。如果为列指定了任何一个,Snowflake 将利用 sequence 生成列的值。

https://docs.snowflake.com/en/sql-reference/sql/create-table.html#optional-parameters

不保证序列中的值是连续的(无间隙),也不保证序列值按特定顺序分配。事实上,除了使用单行语句之外,没有办法将序列中的值以指定的顺序分配给行(这仍然不能保证间隙)。

https://docs.snowflake.com/en/user-guide/querying-sequences.html#sequence-semantics

对于 Snowflake,每个 INSERT 的顺序与 几分钟前运行的相同 INSERT

不,它应该按预期顺序插入数据,因为您使用“ORDER BY”子句。问题是,序列值不是按特定顺序分配的!

当您使用“INSERT/SELECT ORDER BY”时,验证数据是否排序并不容易,除非您有权访问底层元数据。为了进行测试,您可以在摄取“排序”数据的表上定义聚类键。

无论如何,如果要在插入批量数据时分配与顺序匹配的 ID,则需要使用 ROW_NUMBER,而不是使用 IDENTITY 列或任何序列值。

【讨论】:

【参考方案2】:

这不是 Snowflake 中的预期行为。但是,将数据插入表中的方式(按顺序)不会影响数据在表中的存储顺序。您可以在插入中保留订单,但您应该将其包含在您的选择中。

【讨论】:

我尝试了 SELECT 的不同组合(例如将其嵌套在子查询中),但没有任何效果。对 SQL Server 和 PostgreSQL 使用相同的方法会导致根据 ORDER BY 子句进行插入的预期行为。对于 Snowflake,每个 INSERT 的顺序与几分钟前运行的相同 INSERT 的顺序完全不同。

以上是关于雪花使用 ORDER BY 插入不一致的行为的主要内容,如果未能解决你的问题,请参考以下文章

RedShift GROUP BY 常量列给出不一致的结果

雪花算法生成唯一ID,前后端不一致

不同值类型之间的除零行为不一致

Excel 工作表通过 ADODB 不一致的行为导出到 Access

带有 ORDER BY 的雪花 JSON 扁平化

多次连接后,Order by 子句的行为不正确