如何使用单独的字符串表有效地连接记录

时间:2010-11-05 15:05:53

标签: sql-server sql-server-2008 stored-procedures join

我有一个包含大量重复字符串数据的大表。为了节省空间,我已将字符串数据移动到单独的表中。我的表现在看起来像这样:

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的性能?我可以以某种方式把它变成一个连接吗?

strings表在StringId上有一个聚簇主键,所有where字段都在MyRecords表的非聚簇索引中。

3 个答案:

答案 0 :(得分:4)

您可能应该向标准化迈出一步,并创建一个连接表。不是在MyStringNId中包含MyRecords列,而是拥有第三个表:

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上有多个匹配项,那可能会有所帮助。

答案 1 :(得分:2)

  

我能以某种方式将其转变为单一联接吗?

如果在MyRecords的多行中发生相同的组合字符串是很常见的,那么将这些组合存储在单独的表中是有意义的。然后你可以做一次加入。

只要您只存储单个字符串,就不可能在单个连接中执行此操作,因为它必须单独搜索每个字符串。

通过创建包含所有连接的表的视图,可以使查询更易于读取和写入。这不会提高性能,但会使您的查询看起来更好。

  

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

根据数据的形式,您可以做些事情。

如果一个字段中的字符串(大部分)包含的信息与另一个字段不同,那么您可以尝试将它们放入不同的表中。如果一个字段的最大长度比另一个字段的最大长度小得多,或者如果一个字段的不同值的数量远小于另一个字段的数量,则有可能提高性能。

答案 2 :(得分:1)

第一步是运行性能分析以查看问题所在。

尽管如此,你可以通过在连接表上使用(nolock)来获得一些性能提升。