Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 处理大量XML如何不锁定数据库并获得最佳性能?_Sql_Performance_Sql Server 2008_Indexing_Database Locking - Fatal编程技术网

Sql 处理大量XML如何不锁定数据库并获得最佳性能?

Sql 处理大量XML如何不锁定数据库并获得最佳性能?,sql,performance,sql-server-2008,indexing,database-locking,Sql,Performance,Sql Server 2008,Indexing,Database Locking,我有一个数据库过程,它处理一些XML并将其规范化为多个表。 我不是一个数据库高手,也不太了解数据库锁,所以我只是想知道我所做的一切是否完全错了 首先,有一个results表,其中包含类似以下内容: resultId,computerId(int)|rawData(xml) ------------------------------- 1|1|<installedSoftware><software name="Google Chrome" version=

我有一个数据库过程,它处理一些XML并将其规范化为多个表。 我不是一个数据库高手,也不太了解数据库锁,所以我只是想知道我所做的一切是否完全错了

首先,有一个
results
表,其中包含类似以下内容:

resultId,computerId(int)|rawData(xml) ------------------------------- 1|1|<installedSoftware><software name="Google Chrome" version="1.0" /><software name="Mozilla Firefox" version="3.0" /></installedSoftware> 2|2|<installedSoftware><software name="Internet Explorer" version="6" /><software name="Google Chrome" version="1.0" /></installedSoftware> 因此,除此之外,该过程还将处理其他基于计算机的属性,所有属性都来自相同的
结果.rawData
表/列

关于此代码,我的问题如下:

  • 在此处理过程中,其他条目可以不断添加到results.rawData表中。从XML节点中选择来创建临时表需要一些时间,我担心在发生这种情况时,任何试图插入表的操作都可能会被迫等待。通过在过程开始时使用
    resultId
    列,我尝试创建一个过程将一次性处理的数据范围

  • 在此处理期间,可以查询其他表(例如查找计算机上存在的软件)。由于我只在这些表中进行了一次短批量插入,所以我假设在那里应该没有问题

  • #TempSoftware
    表没有索引,我在两个
    NVARCHAR(MAX)
    列上进行了连接。在这个表上创建索引值得吗?或者创建索引的开销会比连接更大吗

  • 我在这里做了什么蠢事,我应该为此挨揍吗


  • 谢谢你的建议。再说一次,我不是一个数据库高手。我假设直接在数据库中进行所有处理比将原始数据拉回到C#中、进行处理并重新插入数据库要好。

    我的方法是添加一个附加的(日期时间)列标记数据,该数据已插入到临时工作表中。处理临时工作表,然后返回以检查新行。这应该是相当轻的。如果需要,它应该在自己的事务中

    通常没有指数=坏,相关指数=好。您应该始终有一个聚集索引,但是根据数据的随机性,该索引可以是紧密压缩的,也可以是填充的。80%是一个很好的起点。Whist复制行时会产生开销。SQL非常适合创建索引,所以插入,然后创建索引是最好的顺序

    如果你认为这类问题会反复出现,你可能想看看SSI——不要指望微软的文档会像一个好的谷歌一样有用,微软在这方面不会改变自己的立场。SSI值得在某些时候加以处理

    CREATE TABLE #ResultsToProcess
    (
       int resultId
    )
    
    -- Only trying to process 1000 results at a time. If I try to do to many at once, I sometimes get timeouts. Instead I do small chunks.
    SELECT
      TOP 1000
      resultId
    FROM
      results
    
    CREATE TABLE #TempSoftware
    (
       computerId INT,
       softwareName NVARCHAR(MAX),
       softwareVersion NVARCHAR(MAX)
    )
    
    INSERT INTO #TempSoftware
    SELECT DISTINCT
      computerId,
      T(N).value('(@name[1])', 'NVARCHAR(MAX)') AS softwareName,
      T(N).value('(@version[1])', 'NVARCHAR(MAX)') AS softwareVersion,
    FROM
      results CROSS APPLY results.rawData.nodes('/installedSoftware[1]/software') AS T(N)
      INNER JOIN #ResultsToProcess ON results.resultId = #ResultsToProcess.resultId
    
    -- May need to do some additional processing on the temporary data before actually using it.
    
    -- To reduce duplicate data, we insert into a full list of software. There is an index based on softwareName and softwareVersion. The softwareTable has an auto increment int primary key.
    INSERT INTO software(softwareName,softwareVersion)
    SELECT DISTINCT softwareName, softwareVersion FROM #TempSoftware
    WHERE NOT EXISTS(SELECT 1 FROM software WHERE software.softwareName = #TempSoftware.softwareName AND software.softwareVersion = #TempSoftware.softwareVersion)
    
    -- Finally we will link any software to the computer. However in this case, the temp table does not have any indexes. Would it be worth-while to add some?
    INSERT INTO computer_software(computerId,softwareId)
    SELECT
      #TempSoftware.computerId,
      #software.softwareId
    FROM #TempSoftware INNER JOIN ON software ON #TempSoftware.softwareName = software.softwareName AND #TempSoftware.softwareVersion = #software.softwareVersion