我正在设计一个SQL架构,我有一个" Contact"带有列的表" LanguagesSpoken"可能有多个值,例如' en,fr'。
我想查询Contact表以检索说出特定语言的每个联系人:
select * from Contact where LanguagesSpoken like '%en%'
然而,这对我来说并不是一个令人满意的解决方案。有没有办法通过索引CSV列的每个单独值来提高性能?
答案 0 :(得分:4)
首先 - 这样做会违反' First Normal Form' - 当且仅当每个属性的域仅包含原子(不可分割)值时
但如果您真的需要这个,请尝试应用full-text index并使用CONTAINS
(https://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();
现在让我们看看估算值:
此外,如果您无法以分隔方式存储数据,请使用此处的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'