2010-11-05 63 views
1

我有一個包含大量重複字符串數據的大表。爲了節省空間,我將字符串數據移到了一個單獨的表格中。我現在的表看起來是這樣的:如何高效地將記錄與單獨的字符串表聯繫起來

MyRecords 
RecordId (int) | FieldA (int) | FieldB (datetime) | FieldC (...) | MyString1Id (int) | MyString2Id (int) | MyString3Id (int) | ... 

MyStrings 
StringId (int) | StringValue (varchar) 

MyRecords表中有大約10外鍵的字符串表。我有一個存儲過程GetMyRecords,它檢索包含實際字符串值的記錄列表。這就是現在SP有10加入到字符串表中的每個字符串關係:

SELECT [Field1], [Field2], [Field3], ..., [Strings1].[StringValue], [Strings2].[StringValue], ... 
FROM MyRecords INNER JOIN 
    MyStrings AS Strings1 ON MyRecords.MyString1Id = Strings1.StringId INNER JOIN 
    MyStrings AS Strings2 ON MyRecords.MyString2Id = Strings2.StringId INNER JOIN 
    MyStrings AS Strings3 ON MyRecords.MyString3Id = Strings3.StringId INNER JOIN 
      (more joins) 
    WHERE [Field1] = @Field1 AND [Field2] = @Field2 

GetMyRecords是相當慢的,比我想因爲所有的連接。我怎樣才能提高這個sp的性能?我可以以某種方式將它變成單個連接嗎?

字符串表在StringId上有一個羣集主鍵,並且所有where字段位於MyRecords表的非聚簇索引中。

+1

你真的應該正常化你的結構,儘管...這不是真正可擴展的,並且會很難維持。 – JNK 2010-11-05 15:13:12

回答

2

我可以以某種方式將它變成單個連接嗎?

如果是串的相同組合上的MyRecords多個行發生共同那麼將是有意義的那些組合存儲在一個單獨的表。然後你可以做一個單一的連接。

只要你只存儲單個字符串,那麼它不可能在單個連接中完成,因爲它必須單獨搜索每個字符串。

通過創建包含所有連接的表的視圖,可以使查詢更易於讀寫。這不會提高性能,但它會使您的查詢看起來好多了。

我該如何提高此sp的性能?

根據數據的形式,您可以執行某些操作。

如果一個字段中的字符串包含(大部分)與另一個字段不同的信息,那麼您可以嘗試將它們放入不同的表中。如果一個字段的最大長度比另一個字段的最大長度小得多,或者一個字段的不同值的數量比另一個字段的數量小得多,那麼這可能會提高性能。

1

第一步是運行性能分析,看看問題出在哪裏。

儘管如此,您可以通過在連接的表上使用(nolock)來獲得性能提升。

4

您應該朝標準化邁出一步,並創建一個連接表。而不必在MyRecordsMyStringNId列,有一個第三個表:

CREATE TABLE RecordsStrings (
    RecordId [theDataType] NOT NULL REFERENCES MyRecords (RecordId), 
    StringId [theDataType] NOT NULL REFERENCES MyStrings (StringId) 
) 

這是不方便再有從SELECT同一行返回的數據的所有字符串(儘管也許有辦法做到這與莫名其妙樞軸),所以它可能會更好重組調用代碼,處理結果的返回:

SELECT [StringValue] 
FROM [MyStrings] s 
INNER JOIN [RecordsStrings] rs ON rs.StringId = s.StringId 
INNER JOIN [MyRecords] r ON rs.RecordId = r.RecordId 
WHERE r.Field1 = @Field1 AND r.Field2 = @Field2 

如果需要從MyRecords其他領域,你可以選擇那些爲好,但他們似乎在每一個相關的行中。但是,如果您在Field1和Field2上有多個匹配項,可能會有所幫助。

+0

很好的答案。直到它被解釋爲我之前,我對多對多問題感到沮喪。最好的數據庫書我買過的「數據庫設計爲單純的凡人」Michael J. Hernandez。 ISBN:0-201-69471-9 – 2010-11-06 13:23:53

+0

正常化似乎不可能。我怎麼知道哪個字符串與哪個列一起出現?我將不得不在連接表中添加另一列。 – Carvellis 2010-11-19 11:28:18

+0

@Jappie如果哪個列與哪個字符串一致,那是真的。我做了一個(顯然很差的)假設,即字符串的順序是不相關的。因此,爲了提高性能,根據您的建議,將連接表添加到連接表中可能會更好,而不會像原始問題中的查詢那樣受到多個連接的影響。 – Andrew 2010-11-19 17:25:12