在MSSQL数据库中写入多个数据/行而不影响性能-C#

时间:2019-03-07 08:55:55

标签: c# sql-server parallel-processing architecture database-performance

我有一个API,可以接收一个大的JSON对象(至少约7MB),该JSON由一些嵌套对象组成,如下所示:

[
  {
    "CategoryId": "P1",
    "CategoryName": "Pizza",
    "Products": [
      {
        "ProductId": "PROD700",
        "ProductName": "Pepperoni Feast Large",
        "ProductPrice": "5.5",
        "Choices": [
          {
            "CoiceId": "CH22",
            "ChoiceName": "Crust",
            "Extras": [
              {
                "ExtraId": "EX1",
                "ExtraName": "Classic Hand Tossed",
                "ExtraPrice": "1"
              },
              {
                "ExtraId": "EX2",
                "ExtraName": "Crunchy Thin Crust",
                "ExtraPrice": "1.25"
              }
            ]
          },
          {
            "CoiceId": "CH24",
            "ChoiceName": "Additionals",
            "Extras": [
              {
                "ExtraId": "EX3",
                "ExtraName": "Extra Black Olives",
                "ExtraPrice": "0.325"
              },
              {
                "ExtraId": "EX4",
                "ExtraName": "Extra Jalapeno",
                "ExtraPrice": "0.4"
              }
            ]
          }
        ]
      }
    ]
  }
]

此API将接收JSON并将其保存在队列中,直到另一个后台服务(即控制台应用程序或Windows服务)使用相同的API进行读取,并获得要写入数据库的PENDING请求列表。

实际上,这是一个非常简单的对象,但是我只想分享这个对象的想法和结构,并且我有一个整体式数据库,每秒有很大的流量,所以,我有以下选择通过:

  • 具有一些嵌套循环以将上述数据一一保存在数据库中,我认为这太糟糕了,并且由于多次往返,这将影响数据库性能,此外,这将花费很长时间是时候完成它了。
  • 使用前一个方案但具有并行性,因此,我们可以使用类似Parallel.For之类的方案来尽可能减少执行时间,但是仍然存在许多数据库命中的问题。
  • 为了克服上述两个挑战(执行时间和多个数据库命中),我考虑过将登台表概念与SqlBulkCopy一起使用,因此,我们可以在主数据库或tempdb中拥有一些登台表,然后在插入/批量复制之后,我可以拥有一个存储过程,该存储过程具有MERGE语句,该语句会将这些登台表中的数据插入数据库中的主表中。这里的主要挑战是,如果控制台应用程序同时处理多个请求/对象,这将是一个问题,因为登台表将在SqlBulkCopy期间被锁定,此外,还要从该登台中删除索引在复制过程中使用table会更好,以便尽可能地加快它的速度,但是在MERGE之前,我们应该有索引来加快从这些临时表中读取的过程。挑战来自CREATEDROP索引,这太困难了,不建议这样做,尤其是在以下两种情况下:(1)登台表中有大量数据。 (2),如果我开始创建索引来为MERGE做准备,但与此同时,又有一个SqlBulkCopy正在并行处理另一个请求。

什么问题?这与应用架构有关 ... 简而言之,我想在数据库中执行写入过程而不会影响数据库性能,也不会消耗应用程序和数据库服务器的大量资源。此外,我想解决上面在建议的方案中提到的挑战,例如执行时间,数据库和锁定表的多次往返以及在有并发请求的情况下使用SqlBulkCopy的情况。

我只是在分享我的想法,但是如果您对此场景有更好的想法/实现,我完全愿意听听您的意见。

注释

  • 我正在使用ADO .NET和存储过程来加快整个过程。
  • 每个请求都应在创建/发布后最多5-10分钟内写入数据库。
  • 有时候,我们可以有多个应该并行编写的请求,而从业务的角度来看,顺序处理就不好了。

0 个答案:

没有答案