Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 关于为我将要讲述的一个案例设计一个更快的T-SQL算法的问题_Sql Server_Database_Algorithm_Tsql - Fatal编程技术网

Sql server 关于为我将要讲述的一个案例设计一个更快的T-SQL算法的问题

Sql server 关于为我将要讲述的一个案例设计一个更快的T-SQL算法的问题,sql-server,database,algorithm,tsql,Sql Server,Database,Algorithm,Tsql,情况就是这样 我有一个sql表,它只包含一个数据列,由一些组名组成。下面是桌子的外观: OPEN SYSTEMS SUB GR OPEN SYSTEMS SUB GR (GM/BTIB(1111)/BTITDBL(2222)/BTVY(4444)/ACSVTYSAG INFRASTRUCTURE SOFT SUB GR INFRASTRUCTURE SOFT SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTUGBL(3333)/BTAUSGAG MAIN SERVE

情况就是这样

我有一个sql表,它只包含一个数据列,由一些组名组成。下面是桌子的外观:

OPEN SYSTEMS SUB GR 
OPEN SYSTEMS SUB GR (GM/BTIB(1111)/BTITDBL(2222)/BTVY(4444)/ACSVTYSAG
INFRASTRUCTURE SOFT SUB GR 
INFRASTRUCTURE SOFT SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTUGBL(3333)/BTAUSGAG
MAIN SERVER ONLİNE SYS SUB GR (GM_BTIB(1111)_BTITDBL(2222)_BTSY(5555)_ANBOSAG
MAIN SERVER SUB GR 
MAIN SERVER SUB GR (GM_BTIB(1111)_BTITDBL(2222)_BTVY(4444)_ANBVTYSAG
XTM/YTM SUB GR 
XTM/YTM SUB GR (GM_BTIB(1111)_BTUGBL(3333)_BTAU(6666)_BTABAG
CARDS SUB GR (GM_BTIB(1111)_BTUGBL(3333)_BTKOU(7777)_BTBKAG
SYSTEMS DEV. SUB GR (GM_BTIB(1111)_BTSGBL(8888)_BTPB(9999)_BBASGAG
PERSONAL B. SUB GR 
PERSONAL B. SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTAU(6666)/BTBISAG
继续这样下去。如您所见,有些组有重复的名称,如

PERSONAL B. SUB GR 
PERSONAL B. SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTAU(6666)/BTBISAG
我想做的是,我想用较长版本的组名更新短版本的组名。例如,个人B.SUB GR将替换为个人B.SUB GR GM/BTIB1111/BTUGBL3333/BTAU6666/BTBISAG,如更新后的表格所示

OPEN SYSTEMS SUB GR (GM/BTIB(1111)/BTITDBL(2222)/BTVY(4444)/ACSVTYSAG
OPEN SYSTEMS SUB GR (GM/BTIB(1111)/BTITDBL(2222)/BTVY(4444)/ACSVTYSAG
INFRASTRUCTURE SOFT SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTUGBL(3333)/BTAUSGAG
INFRASTRUCTURE SOFT SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTUGBL(3333)/BTAUSGAG
MAIN SERVER ONLİNE SYS SUB GR (GM_BTIB(1111)_BTITDBL(2222)_BTSY(5555)_ANBOSAG
MAIN SERVER SUB GR (GM_BTIB(1111)_BTITDBL(2222)_BTVY(4444)_ANBVTYSAG
MAIN SERVER SUB GR (GM_BTIB(1111)_BTITDBL(2222)_BTVY(4444)_ANBVTYSAG
XTM/YTM SUB GR (GM_BTIB(1111)_BTUGBL(3333)_BTAU(6666)_BTABAG
XTM/YTM SUB GR (GM_BTIB(1111)_BTUGBL(3333)_BTAU(6666)_BTABAG
CARDS SUB GR (GM_BTIB(1111)_BTUGBL(3333)_BTKOU(7777)_BTBKAG
SYSTEMS DEV. SUB GR (GM_BTIB(1111)_BTSGBL(8888)_BTPB(9999)_BBASGAG
PERSONAL B. SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTAU(6666)/BTBISAG
PERSONAL B. SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTAU(6666)/BTBISAG
我的表由9000条记录组成,我有一个算法可以做到这一点,但是它的运行速度很慢,大约需要3分钟来完成查询,但是我要做的事情很简单。我需要一个更快的算法


谢谢你的帮助

类似的内容可能会有所帮助:

UPDATE grp SET
  name = l.name
FROM grp s, grp l
WHERE LEN(s.name) < LEN(l.name)
  AND s.name = LEFT(l.name, LEN(s.name))

尽管这些重复会伤害你自己…

但用基于集合的方式解决这一问题应该相对简单:

UPDATE a
SET  a.yourfield = b.yourfield 
FROM yourtable a 
INNER JOIN yourtable b on b.yourfield LIKE a.yourfield + '%' AND b.yourfield <> a.yourfield

这将进行模式匹配,但排除自身的匹配-但这并不理想,我猜在此过程之后,您将删除重复项或其他内容,因为有一个包含多个重复项且没有其他区分值的表有点奇怪。

这是我的代码,当grup名称增加时,它会持续大约3分钟,以指数速度增加。我也不能使用它,因为我不应该让数据库在这3分钟内一直处于繁忙状态,而且它也没有未来,因为查询执行时间正在快速增长

UPDATE MYTABLE
SET GRUP=ISNULL(C.BGrup,MYTABLE.Grup)

FROM 
MYTABLE
FULL OUTER JOIN
(
SELECT
AGRUP, BGRUP
FROM
(
    SELECT 
    DISTINCT GRUP AS AGRUP
    FROM 
    MYTABLE
    WHERE GRUP NOT LIKE '%(%(%)%(%)%(%)%'
) A
LEFT JOIN
(
    SELECT 
    DISTINCT 
    REPLACE(GRUP,'_','/') AS BGRUP
    FROM 
    MYTABLE
    WHERE GRUP LIKE '%(%(%)%(%)%(%)%'
) B
ON 

AGRUP = SUBSTRING(BGRUP,0,LEN(AGRUP)+2)

WHERE 
AGRUP <> '' AND 
BGRUP <> '' AND
) C
ON MYTABLE.Grup=C.AGrup

使用SQLServer2000

测试数据:

create table #t (grup varchar(200))

insert into #t values ('OPEN SYSTEMS SUB GR')
insert into #t values ('OPEN SYSTEMS SUB GR (GM/BTIB(1111)/BTITDBL(2222)/BTVY(4444)/ACSVTYSAG')
insert into #t values ('INFRASTRUCTURE SOFT SUB GR')
insert into #t values ('INFRASTRUCTURE SOFT SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTUGBL(3333)/BTAUSGAG')
insert into #t values ('MAIN SERVER ONLİNE SYS SUB GR (GM_BTIB(1111)_BTITDBL(2222)_BTSY(5555)_ANBOSAG')
insert into #t values ('MAIN SERVER SUB GR')
insert into #t values ('MAIN SERVER SUB GR (GM_BTIB(1111)_BTITDBL(2222)_BTVY(4444)_ANBVTYSAG')
insert into #t values ('XTM/YTM SUB GR')
insert into #t values ('XTM/YTM SUB GR (GM_BTIB(1111)_BTUGBL(3333)_BTAU(6666)_BTABAG')
insert into #t values ('CARDS SUB GR (GM_BTIB(1111)_BTUGBL(3333)_BTKOU(7777)_BTBKAG')
insert into #t values ('SYSTEMS DEV. SUB GR (GM_BTIB(1111)_BTSGBL(8888)_BTPB(9999)_BBASGAG')
insert into #t values ('PERSONAL B. SUB GR')
insert into #t values ('PERSONAL B. SUB GR (GM/BTIB(1111)/BTUGBL(3333)/BTAU(6666)/BTBISAG')

insert into #t
select L.*
from #t L
cross join #t R

insert into #t
select L.*
from #t L
cross join #t R
提供vver 33000测试行

步骤1,构建临时表以保存从短组名到长组名的转换:

select substring(grup, 1, charindex(' (', grup)) as short_grup
    , grup as long_grup
into #Lookup
from #t
WHERE GRUP LIKE '%(%(%)%(%)%(%)%'
group by grup
步骤2,在update语句中使用上述临时表:

update target
    set target.grup = source.long_grup
from #t target
inner join #Lookup source
on target.grup = source.short_grup
注意:我尝试在一个步骤中使用内联视图,但目前需要7分钟以上的时间:

update target
    set target.grup = source.long_grup
from #t target
inner join (select substring(grup, 1, charindex(' (', grup)) as short_grup
        , grup as long_grup
    from #t
    WHERE GRUP LIKE '%(%(%)%(%)%(%)%'
    group by grup) source
on target.grup = source.short_grup
其他需要考虑的事情

若您的组名是稳定的,那个么使用从短到长的名称映射构建一个永久表,而不是每次都创建一个临时表。 短名称和grup上的索引可能会加快连接速度。测试看看。 输入短名称的系统可以修复吗?
我用SELECT而不是UPDATE尝试了你的代码,即使这样,它也会持续超过1分钟,我不得不手动停止。你已经索引了我接受的字段?我不明白你的意思。我就是这样用你的代码的。从yourtable a中选择a.ID在b.GRUP上内部连接yourtable b,如a.GRUP+“%”和b.GRUP a.GRUP它没有停止,我手动在1分30秒时停止了它,它返回365.868条记录并继续。顺便说一句,像select*FROM myTable这样的普通选择会在0秒内返回该表。因此,我的数据库没有问题。Select*from yourtable可能会在0秒后返回,因为一个9000行的表将被存储在内存中并被缓存—特别是考虑到您所做的所有测试—这并不明确表示“我的数据库没有问题”。告诉我们表上有哪些索引,包括聚集索引和非聚集索引,以及包含哪些字段。另外,请告诉我们每个测试是使用DBCC DropCleanBuffers和DBCC FreeProcCache干净地开始的,还是使用预热缓存。我有两个表的主键,我不知道您说的是什么。我不知道sql server中有缓存,我不知道如何检查它。我读过dbcc dropcleanbuffers的定义,但我没有弄清楚。一个有9000条记录的表格绝对不会花那么长时间。你没有告诉我们什么重要的事情。下面是我如何使用你的代码从grp s,grp l中选择s.ID,其中LENs.GRUP