我们有三个表存储文档信息,我称之为表A,B和C.表A存储所述文档的主要字段(例如文件名和大小以及其他一般信息)。为了动态添加新字段,我们使用表B来存储新字段及其数据类型的列表(由枚举确定),并使用表C来存储这些字段的值。
Table A
ID - PK int
FieldX...
FieldY...
FieldZ...
Table B
Id - PK int
Name - nvarchar(max)
Type - int
Table C
Id - PK int
AId - FK to table A int
BId - FK to table B int
Value - nvarchar(max)
我们想要尽可能高效地做的是将表C中的值作为表A中查询中的附加列。现在,这是我为表B中的每个额外字段执行此操作的方法。 / p>
select (select c.value
from B b, C c
where c.AId = a.Id
and c.Bid = b.Id
and b.Name = 'Dynamic Field Name') As 'Dynamic Field Name'
From A a
我们有一个表A填充了36000行的数据库。对于添加到查询的每个其他动态字段,它会在完成查询的总时间上添加大约4秒,使包含10个动态字段的查询至少需要40秒。实际上,我们希望任何查询都在10以下完成。有没有办法更有效地写这个?
答案 0 :(得分:0)
首先,您的查询可能会给您错误,因为您没有将C.(A + B)定义为唯一。如果C中每个A+B
组合有多个值,则会导致子查询失败并显示
Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value.
假设它是唯一的,那么你应该安全地将它们连接在一起以便使用基于SET的操作。
select a.*,
c1.value [Dynamic Field Name 1],
c2.value [Dynamic Field Name 2]
From A a
JOIN B b1 on b1.Name = 'Dynamic Field Name1'
LEFT JOIN C c1 on c1.AId = a.Id and c.Bid = b1.Id
JOIN B b2 on b2.Name = 'Dynamic Field Name2'
LEFT JOIN C c2 on c2.AId = a.Id and c2.Bid = b2.Id
在SELECT级别使用子查询会强制每条记录,并且每个动态字段都以mini-select =非常慢的速度执行。
答案 1 :(得分:0)
也许像这样的查询也会起作用:
select a.id
,MAX(CASE WHEN b.Name = 'Dynamic Field Name' THEN c.value END) As Dynamic_Field_Name
,MAX(CASE WHEN b.Name = 'Dynamic Field Name 2' THEN c.value END) As Dynamic_Field_Name2
from A a, B b, C c
where c.AId = a.Id
and c.Bid = b.Id
and b.Name IN ('Dynamic Field Name', 'Dynamic Field Name 2')
group by a.id
同样的想法,你只想在表中进行一次传递,而不是每行查找一次。聚合是将稀疏矩阵压缩成单行(即,一行中只有一个动态字段值,每行具有一个具有值的不同列)。不知道它会如何表现。