Sql 处理大量XML如何不锁定数据库并获得最佳性能?
我有一个数据库过程,它处理一些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=
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
表/列
关于此代码,我的问题如下:
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