【问题标题】:optimise sql function to get common elements优化sql函数获取常用元素
【发布时间】:2012-05-13 23:33:16
【问题描述】:

我有一个函数,它接受两个分隔字符串并返回公共元素的数量。

函数的主要代码是(@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 个字符。

有没有我能以足够快的速度达到这个速度以供使用?

【问题讨论】:

  • 这是你需要一直运行的东西,还是一次性的?
  • 我正在运行一些数据挖掘模拟,所以每当我的模型发生变化或我想尝试新的公式时都需要这样做。可能不是很频繁

标签: sql optimization sql-server-2008-r2


【解决方案1】:

性能问题可能是光标(用于 while 循环)和用户定义函数的组合。

如果这些字符串中的一个是常量(例如item关键字),您可以单独搜索每一个:

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.keyword

SQL 引擎会发挥它的魔力。

现在,您如何创建这样的列表?如果每个用户只有几个关键词,那么您可以执行以下操作:

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 user

【讨论】:

  • 我正在考虑采用基于表格的方法。我得到的数据是我上传到表格的格式的平面文件。它们没有标准化,大小约为 2-3 gigs
  • 我会使用 powershell 来拆分数据,然后以标准化格式加载它。如果您已经在表格中有数据,请尝试电子邮件中的方法。它可能比您预期的更好,特别是如果您在多处理器机器上运行。您最初的方法可能是序列化查询,因此它没有利用您的所有硬件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 2017-03-31
  • 1970-01-01
相关资源
最近更新 更多