我正在处理U-SQL中的数据,但没有得到预期的结果。这就是我在做的事情:
1- Select data from ADL table partitions and assign it to @data1
2- Aggregate data using Group BY and assign it to @data2
3- Truncate partitions
4- Insert data(produced in step 2) into the same table
5- Use @data2 and generate a unique GUID for every record using user
defined function and assign it to @data2
//UDF Code
public static Guid GetNewGuid ()
{
return Guid.NewGuid ();
}
6- Select few columns from @data2 and assign it to @data3
@ data2和@ data3中的奇怪GUID完全不同。
如果我与其他数据集执行某些连接并在步骤5中更改模式然后生成唯一的GUID,那么我在最后一步获得相同的GUID。看起来在创建此问题的后端发生了一些脚本优化。
您能告诉我上述工作流程中出现的问题吗?或者,如果在后端发生某种优化,那么如何学习脚本优化的工作原理。
更新 在这个问题中,我的重点是了解为什么在一步中计算出来的东西会在下一步自动改变。
答案 0 :(得分:2)
回答更新的焦点 - 为什么在一步中计算的某些内容会在下一步自动更改
wBob的摘录完全回答了IMO的问题,但也许更广泛的背景会有所帮助。
语义,答案就是
未定义意味着任何事情都可能发生,因此您不能期望 - 一致的价值观或其他方面。任何关于实际行为的讨论(不同的Guids)都是实现细节。
语义深度
步骤是一种错觉。
C#等命令式语言中的语句是一系列精确的说明(如何)。
U-Sql等函数式语言中的语句是需求列表,以输入(what)描述输出。 U-Sql优化器在满足这些要求方面具有完全的实现灵活性。行集是组织用户需求的逻辑结构,它们实际上不需要在实现时存在;而对应行集的逻辑可以在实现中拆分,合并,跳过,重复等。
因此,例如,确定性要求下的步骤5,6的完全合法的实施:
@data3 = SELECT <FewCols>, GetNewGuid() AS NewGuid FROM @data2;
@data2 = SELECT *, GetNewGuid() AS NewGuid FROM @data2;
答案 1 :(得分:0)
欢迎来到Nabeel湖。期待您的更多答案!
此外,非确定性函数的行为有点复杂,因为对于某些函数,如果它们出现在U-SQL中但在C#之外,我们将它们设置为确定性(例如,DateTime.Now())代码块(例如,用户定义的函数),但它们在C#代码块中保持不确定性。
创建密钥的推荐方法是一种称为Skolemization的技术,您可以使用基于标识属性的确定性密钥生成。这样你就保持了确定性。