SQL 或 C# 配对速度更快吗?

本文关键字:速度 SQL | 更新日期: 2023-09-27 18:35:52

我有很多数据需要根据一些简单的标准进行配对。 有一个时间窗口(两个记录都有一个 DateTime 列),如果一条记录在时间上(5 秒内)与另一条记录非常接近,则它是潜在的匹配,时间最接近的记录被视为完全匹配。 还有其他领域也有助于缩小范围。

我编写了一个存储过程,它在返回与 C# 应用程序匹配的完整数据集。 我的问题是,拉入 100 万 (x2) 行并在 C# 中处理它们会更好,还是 sql 服务器更适合执行这种匹配? 如果是 SQL 服务器,那么使用日期时间字段配对数据的最快方法是什么?

现在,我将表 1/表 2 中的所有记录选择到临时表中,遍历表 1 中的每条记录,在表 2 中查找匹配项并将匹配项(如果存在)存储在临时表中,然后删除它们自己的临时表中的两条记录。

不得不为我正在编写的游戏匆忙写这篇文章,所以请原谅糟糕(非常糟糕)的程序......它有效,只是效率极低! 整个 SP 可在 pastebin 上使用:http://pastebin.com/qaieDsW7

我知道SP写得很差,所以说"嘿,笨蛋...写得更好"无济于事! 我正在寻求改进它的帮助,或者关于我应该如何以不同的方式做整个事情的帮助/建议! 我有大约 3/5 天的时间来重写它,我可以将截止日期推迟一点,但如果你们能及时帮助我,我宁愿不要!:)

谢谢!

SQL 或 C# 配对速度更快吗?

最终,在数据库端编译数据在99%的情况下是可取的,因为它是为数据处理而设计的(通过使用索引,关系等)。通过使用联接,可以完全按照所需的格式编译数据,从而合并许多代码。事实上,您可以完全绕过几乎所有的临时表,只填满一个主事件临时表。

一般模式是这样的:

INSERT INTO #Events
SELECT <all interested columns>
FROM 
    FireEvent
    LEFT OUTER JOIN HitEvent ON <all join conditions for HitEvent>

通过这种方式,您可以将所有火灾事件与零个或多个命中事件匹配。在聊天中讨论之后,您甚至可以将其限制为零个或一个命中事件,方法是将其包装在子查询中并使用窗口函数进行ROW_NUMBER() OVER (PARTITION BY HitEvent.EventID ORDER BY ...) AS HitRank并向外部查询添加WHERE HitRank = 1。这最终是你最终所做的,并得到了你期望的结果(在这个过程中有一些工作和学习)。

如果数据已经在数据库中,那么您应该在那里执行工作。 您绝对应该学习使用 SQL Server Management Studio 显示和查询计划,并能够注意到并优化昂贵的计算,如嵌套循环。

您的任务可能不需要使用任何临时表。 当临时表相对较小和/或大量重复使用时,它们往往效率很高,但事实并非如此。

如果运行速度不够快,我建议您尝试优化存储过程,并且不要用 C# 重写它。为什么要从 SQL Server 中传输数百万行?

不幸的是,我没有安装 SQL Server,所以我无法测试您的脚本,但我在那里没有看到任何 CREATE INDEX 语句。如果您只是为了简洁而跳过它们,那么您肯定应该分析您的查询并查看需要哪些索引。

因此,答案取决于几个因素,例如每个客户端/服务器的可用资源(Ram/CPU/并发用户/并发进程等)。

以下是一些基本规则,无论您使用什么,它们都可以提高您的性能:

  • 将一百万行加载到 c# 程序中不是一个好的做法。除非这是一个具有大量内存的独立过程。
  • 唯一标识符永远不会超过整数。比较
  • 公用表表达式是快速执行匹配的良好替代方法。如何使用 CTE
  • 最后,您必须考虑输出。如果存在影响用户界面的常量读取和写入,则应在内存 (c#) 中进行管理,否则所有 CRUD 操作都应保留在数据库中。