0

具有以下表结构:

表 1:客户

CustID(primary key)  |  CustName(indexed)
----------------------------------
C1                       Cust1
C2                       Cust2
.                        Cust3
.                        Cust.
.                        Cust.
C10000                   Cust10000

表 2:自定义字段

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

更新 :

CustomFieldstable 是一个通用表,它可以包含任何其他实体(供应商、项目等)的字段。

4

4 回答 4

1

您是否尝试过使用数据库引擎优化顾问分析查询?不能保证,但它可能会提供一两个有用的建议。

在此处输入图像描述

于 2012-05-22T16:33:59.463 回答
0

你的询问是完全合理的。但是,数据库结构已关闭。您应该有一个单独的列用于客户 ID 和字段 ID。按照编写查询的方式,您将获得与其他表中的字段一样多的 CustId 行。

它们不应该组合成一列。我希望加入看起来像:

left outer join
CustomerFields cfn
on cfn.CustId = Customers.CustId and
   cfn.FieldNum = <n>

另一种可能性是性能下降是您第一次运行查询。如果您有足够的内存,那么它第二次运行的速度可能会快得多——因为字段表在内存中。

为了记录,我对“喜欢”有一个历史偏见,认为它会导致性能问题。这可能无济于事,但您可以尝试:

where left(CustName, 1) = 'C'
于 2012-05-22T14:57:52.503 回答
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
于 2012-05-23T06:21:00.990 回答
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
于 2012-05-24T12:49:29.940 回答