我有2个表(SQL Server 2008):Documents and Fields。
文件:
Id (PK)
Some-Others-Columns
字段:
Id (PK)
DocumentId (FK to Documents)
Name
Value
每个文档都分配了80多个字段。我必须选择一个表,其中每一行都是一个文档+一些特定的字段(不是80+,只有一些字段)。
我的T-SQL代码对大表的工作速度非常慢,我该如何优化呢?
SELECT f1.Value AS 'f1', f2.Value AS 'f2', f3.Value AS 'f3', f4.Value AS 'f4', f5.Value AS 'f5', f6.Value AS 'f6', d.PartyId, d.CreationDate
FROM dbo.Fields AS f WITH (NOLOCK)
INNER JOIN dbo.Fields AS f1 ON f.Id = f1.Id
INNER JOIN dbo.Documents AS d ON f1.DocumentId = d.Id
INNER JOIN dbo.Fields AS f2 ON d.Id = f2.DocumentId
INNER JOIN dbo.Fields AS f3 ON d.Id = f3.DocumentId
INNER JOIN dbo.Fields AS f4 ON d.Id = f4.DocumentId
INNER JOIN dbo.Fields AS f5 ON d.Id = f5.DocumentId
INNER JOIN dbo.Fields AS f6 ON d.Id = f6.DocumentId
WHERE
(f1.Name = 'Some-Name-1')
AND (f2.Name = 'Some-Name-2')
AND (f3.Name = 'Some-Name-3')
AND (f4.Name = 'Some-Name-4')
AND (f5.Name = 'Some-Name-5')
AND (f6.Name = 'Some-Name-6')
请帮助我优化此查询
答案 0 :(得分:2)
不确定枢轴是否会表现更好,您需要将其与文档连接起来以获取其他文档字段。我的语法可能有点偏离(如果您希望我修复它,您可以设置一个SQL小提琴,其中插入了两个表和示例行:http://sqlfiddle.com/)
SELECT DocumentId,
[Some-Name-1], [Some-Name-2], [Some-Name-3], [Some-Name-4], [Some-Name-5],[Some-Name-6]
FROM (
Select f.DocumentId, f.Name, f.Value
FROM dbo.Fields AS f
INNER JOIN dbo.Documents AS d ON f.DocumentId = d.Id ) as SourceTable
PIVOT
(
SUM(Value)
FOR Name IN ([Some-Name-1], [Some-Name-2], [Some-Name-3], [Some-Name-4], [Some-Name-5],[Some-Name-6])
) AS PivotTable;
答案 1 :(得分:1)
您可以使用ctrl + l查看执行计划以及执行时间最长的内容。您很可能希望在字段表的ID和名称索引以及文档表上的ID
答案 2 :(得分:1)
高性能成本来自于拥有如此多的连接。 为什么不获取所需文档的“字段”的记录集? 也许我没弄错......
SELECT value
FROM Documents AS d
INNER JOIN Fields as f ON d.Id=f.DocumentId
WHERE (f.Name="Name1" or f.Name="Name2" or.. etc);
你应该在Document
的字段中拥有所有“Value”列的记录集如果您需要形成列的值,则应在第一次查询后执行此操作
答案 3 :(得分:1)
试试这个:
SELECT f1.Value AS 'f1', f2.Value AS 'f2', f3.Value AS 'f3', f4.Value AS 'f4', f5.Value AS 'f5', f6.Value AS 'f6', d.PartyId, d.CreationDate
FROM dbo.Fields AS f WITH (NOLOCK)
INNER JOIN (SELECT Id, DocumentId, Value FROM dbo.Fields WHERE Name='Some-Name-1') AS f1
ON f.Id = f1.Id
INNER JOIN (SELECT Id, CreationDate, PartyId FROM dbo.Documents) AS d
ON f1.DocumentId = d.Id
INNER JOIN (SELECT Id, DocumentId, Value FROM dbo.Fields WHERE Name='Some-Name-2') AS f2
ON d.Id = f2.DocumentId
INNER JOIN (SELECT Id, DocumentId, Value FROM dbo.Fields WHERE Name='Some-Name-3') AS f3
ON d.Id = f3.DocumentId
INNER JOIN (SELECT Id, DocumentId, Value FROM dbo.Fields WHERE Name='Some-Name-4') AS f4
ON d.Id = f4.DocumentId
INNER JOIN (SELECT Id, DocumentId, Value FROM dbo.Fields WHERE Name='Some-Name-5') AS f5
ON d.Id = f5.DocumentId
INNER JOIN (SELECT Id, DocumentId, Value FROM dbo.Fields WHERE Name='Some-Name-6') AS f6
ON d.Id = f6.DocumentId