雪花使用 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 插入不一致的行为的主要内容,如果未能解决你的问题,请参考以下文章