有没有办法有效地索引逗号分隔列的每个值?

时间:2016-06-07 07:08:09

标签: sql tsql

我正在设计一个SQL架构,我有一个" Contact"带有列的表" LanguagesSpoken"可能有多个值,例如' en,fr'。

我想查询Contact表以检索说出特定语言的每个联系人:

select * from Contact where LanguagesSpoken like '%en%'

然而,这对我来说并不是一个令人满意的解决方案。有没有办法通过索引CSV列的每个单独值来提高性能?

3 个答案:

答案 0 :(得分:4)

首先 - 这样做会违反' First Normal Form' - 当且仅当每个属性的域仅包含原子(不可分割)值时

但如果您真的需要这个,请尝试应用full-text index并使用CONTAINShttps://technet.microsoft.com/en-us/library/ms187787(v=sql.110).aspx

进行全字匹配搜索

答案 1 :(得分:1)

在摘要中,如果要将数据存储在逗号分隔列表中,则没有可以提供良好性能的索引。

即使您使用类似条件,如果字符串上的索引少于80个字符,则SQL可以准确猜测string statistics。如果字符串超过80个字符,则前40个字符和后40个字符在这个字符串列上创建统计信息。除此之外,您使用类似的方式查询数据和存储数据的方式没有任何优势。

演示:

$('#ressource_regions_region_id').selectpicker();

现在让我们看看估算值:

enter image description here

此外,如果您无法以分隔方式存储数据,请使用此处的string functions之一查询数据的准确方法如下所示。

create table 
#test
(
id int,
langspoken varchar(100)
)


insert into #test
select 1,'en,fr,ger,en_us'
union all
select  2,'en,fr'
go 100

create  index nci on #test(langspoken)

select * from #test where langspoken like '%fr%'

答案 2 :(得分:1)

请尝试以下代码。它使用SQL Server 2012。

DECLARE @Table TABLE (ID int, Languages Varchar(10))
INSERT @Table
(ID,Languages)
VALUES
(1, 'en,fr,ge'),
(2, 'en,ky,ge'),
(3, 'hi,fr,ge')


SELECT ID ,Languages FROM
    (
     SELECT 
         A.ID AS ID,  
         Split.a.value('.', 'VARCHAR(100)') AS Languages  
     FROM  (
            SELECT 
                ID,  
                CAST ('<M>' + REPLACE(Languages, ',', '</M><M>') + '</M>' AS XML) AS Languages  
            FROM  
                @Table A
             )  AS A 
    CROSS APPLY Languages.nodes ('/M') AS Split(a)
    ) AS B
WHERE B.Languages ='en'