使用以下表格结构:
表1:客户
CustID(primary key) | CustName(indexed)
----------------------------------
C1 Cust1
C2 Cust2
. Cust3
. Cust.
. Cust.
C10000 Cust10000
表2: CustomFields
FieldID (primary key) | ID (indexed) | FieldValue
---------------------------------------------------------------------
1 C1 Test
2 C2 Test
3 C3 Test
4 C4 Test
. . Test
. . Test
few millions Z1 Test
"ID" column is indexed.
尝试输出以下内容;
CustID | Field 1 | Field 2 | Field 3 | .... | Field N
----------------------------------------------------------
我尝试编写像
这样的查询Select
CustID, A1.FieldValue as [Field 1], A2.FieldValue as [Field 2]
from
Customers
left outer join
CustomFields A1 on Customers.custID = A1.ID
left outer join
CustomFields A2 on Customers.custID = A2.ID
left outer join
CustomFields An on Customers.custID = An.ID
where
custName like 'C%'
由于CustomFields
表包含几百万条记录,因此上述查询效果不佳。现在需要大约10-12秒(500个客户和6个领域)
我认为左外连接在这里增加了时间。任何解决问题的想法都会有所帮助吗?
平台:SQL Server 2005
更新:
CustomFields
表是一个通用表,它可以包含任何其他实体(供应商,项目等)的字段。
答案 0 :(得分:1)
您是否尝试过使用数据库引擎优化顾问分析查询?没有保证,但它可能会提供一两个有用的建议。
答案 1 :(得分:0)
你的查询是完全合理的。但是,数据库结构已关闭。您应该为客户ID和字段ID分别创建一个列。编写查询的方式,您将获得与另一个表中的字段一样多的CustId行。
它们不应合并为一列。我希望联接看起来像:
left outer join
CustomerFields cfn
on cfn.CustId = Customers.CustId and
cfn.FieldNum = <n>
另一种可能性是性能命中是您第一次运行查询。如果你有足够的内存,那么它第二次可能运行得更快 - 因为fields表在内存中。
为了记录,我对“喜欢”有历史偏见,相信它会导致性能问题。这可能没有帮助,但您可以尝试:
where left(CustName, 1) = 'C'
答案 2 :(得分:0)
SELECT Pvt.ID,
Customers.CustName,
Pvt.[1] AS Field1,
Pvt.[2] AS Field2,
Pvt.[3] AS Field3,
Pvt.[4] AS Field4,
Pvt.[5] AS Field5,
...
FROM (
SELECT ID, FieldID, FieldValue
FROM CustomFields) AS p
PIVOT (
MIN (FieldValue)
FOR FieldID IN ([1], [2], [3], [4], [5], ... )
) AS pvt
inner join Customers ON Customers.CustID = pvt.ID
答案 3 :(得分:0)
您可以使用单个联接来获取自定义字段,并使用聚合函数来转置它们。这样,与表CustomFields的连接只进行一次。
喜欢这个。
SELECT
Customers.CustID,
MAX(CASE WHEN CF.FieldID = 1 THEN CF.FieldValue ELSE NULL END) AS Field1,
MAX(CASE WHEN CF.FieldID = 2 THEN CF.FieldValue ELSE NULL END) AS Field2,
MAX(CASE WHEN CF.FieldID = 3 THEN CF.FieldValue ELSE NULL END) AS Field3,
MAX(CASE WHEN CF.FieldID = 4 THEN CF.FieldValue ELSE NULL END) AS Field4
-- Add more...
FROM Customers
LEFT OUTER JOIN CustomFields CF
ON CF.ID = Customers.CustID
WHERE Customers.CustName like 'C%'
GROUP BY Customers.CustID