我有一个函数,它接受两个分隔字符串,并返回公共元素的数量。这个
函数的主代码为(@intCount为预期返回值)
SET @commonCount = (select count(*) from (
select token from dbo.splitString(@userKeywords, ';')
intersect
select token from dbo.splitString(@itemKeywords, ';')) as total)其中,splitString使用while循环和charIndex将字符串拆分成分隔的标记,并将其插入到表中。
我遇到的问题是,这只能以每秒100行的速度进行处理,根据我的数据集的大小,这将需要大约8-10天的时间才能完成。
这两个字符串的长度最多可达1500个字符。
有没有什么方法可以让我足够快地做到这一点,使其变得有用?
发布于 2012-05-13 23:33:17
性能问题可能是游标(用于while循环)和用户定义函数的组合。
如果其中一个字符串是常量(例如项目关键字),则可以单独搜索每个字符串:
select *
from users u
where charindex(';'+<item1>+';', ';'+u.keywords) > 0
union all
select *
from users u
where charindex(';'+<item2>+';', ';'+u.keywords) > 0 union all或者,基于集合的方法也可以工作,但您必须对数据进行规范化(在这里插入,以便一开始就拥有正确格式的数据)。也就是说,您需要一个具有以下内容的表:
userid
keyword另一种是
itemid
keyword(如果有不同类型的项目。否则,这只是一个关键字列表。)
然后,您的查询将如下所示:
select *
from userkeyword uk join
itemkeyword ik
on uk.keyword = ik.keywordSQL引擎就会施展它的魔力。
那么,如何创建这样的列表呢?如果每个用户只有几个关键字,那么可以这样做:
with keyword1 as (select u.*, charindex(';', keywords) as pos1,
left(keywords, charindex(';', keywords)-1) as keyword1
from user u
where charindex(';', keywords) > 0
),
keyword2 as (select u.*, charindex(';', keywords, pos1+1) as pos2,
left(keywords, charindex(';', keywords)-1, pos1+1) as keyword2
from user u
where charindex(';', keywords, pos1+2) > 0
),
...
select userid, keyword1
from keyword1
union all
select userid, keyword2
from keyword2
...要获取itemKeyWords中元素的最大数量,可以使用以下查询:
select max(len(Keywords) - len(replace(Keywords, ';', '')))
from userhttps://stackoverflow.com/questions/10572858
复制相似问题