Chr*_*ium 0 performance sql-server query-performance
我有一个包含 700,000 行的表,其中包含一个字符串 id 字段,其值例如 rec-232276-dup-0 和 rec-354240-org。rec- 是常数,但 id 的其他部分可以改变。
我想拆分这个字符串,以便我只有整数部分和一个布尔值,具体取决于下一部分是否等于 dup 或 org(1 表示 dup,0 表示 org),我将其插入回表中。
我编写了以下循环来执行此操作,并且在功能上它运行良好,但是当我在完整的 700,000 行上运行它时,它需要非常长的时间(+12 小时和计数)。
我做错了什么导致它花费这么多时间?这是导致这种情况的字符串操作吗?我可以做些什么来改善这种情况?
谢谢你的帮助。
我的脚本如下:
select id
into #ControlTable
from [dbo].[original_test_dataset]
declare @TableID varchar(20)
while exists (select * from #ControlTable)
begin
select @TableID = (select top 1 id
from #ControlTable
order by id asc)
declare @duplicate bit
declare @id_only varchar(10)
--1. Find id only
-- Trim off rec-
set @id_only = REPLACE(@TableID,'rec-','')
-- Find position of first - and then take everything before it
set @id_only = LEFT(@id_only,CHARINDEX('-',@id_only,0))
set @id_only = REPLACE(@id_only,'-','')
UPDATE original_test_dataset set id_only = @id_only WHERE id = @TableID;
--2. Find if duplicate
IF(PATINDEX('%dup%',@TableID) = 0)
BEGIN
-- No duplicate so original file
UPDATE original_test_dataset set duplicate = 0 WHERE id = @TableID;
END
ELSE
BEGIN
-- Duplicate
UPDATE original_test_dataset set duplicate = 1 WHERE id = @TableID;
END
delete #ControlTable
where id = @TableID
END
drop table #ControlTable
Run Code Online (Sandbox Code Playgroud)
根据要求添加表定义:
CREATE TABLE [dbo].[original_test_dataset](
[id] [varchar](50) NULL,
[ FirstName] [varchar](50) NULL,
[ LastName] [varchar](50) NULL,
[ Phone1] [varchar](50) NULL,
[ Phone2] [varchar](50) NULL,
[ Phone3] [varchar](50) NULL,
[ No] [varchar](50) NULL,
[ Road] [varchar](50) NULL,
[ Village] [varchar](50) NULL,
[ Town] [varchar](50) NULL,
[ PC] [varchar](50) NULL,
[ County] [varchar](50) NULL,
[ DOB] [varchar](50) NULL,
[id_only] [varchar](10) NULL,
[duplicate] [bit] NULL
) ON [PRIMARY]
GO
/****** Object: Index [PK_ORIGINAL_TEST_DATASET_ID] Script Date: 03/09/2014 07:47:19 ******/
CREATE CLUSTERED INDEX [PK_ORIGINAL_TEST_DATASET_ID] ON [dbo].[original_test_dataset]
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
您有一个性能问题,因此我建议您首先阅读如何分析 SQL Server 性能。
至于您的脚本:您正在尽可能慢地进行。一排排痛苦地慢排。甚至游标慢也不比游标慢。您在这里拥有的是一个更新:
update original_test_dataset
set duplicate= case when PATINDEX('%dup%', id)=0 then 0 else 1 end,
id_only = REPLACE((LEFT(REPLACE(id,'rec-',''), CHARINDEX('-',REPLACE(id,'rec-',''),0)),'-','');
Run Code Online (Sandbox Code Playgroud)
就是这样,没有别的。
原始脚本中的内容很慢,因为:
#ControlTable
(每个操作 #ControlTable
都是无索引的端到端扫描,它应该有一个索引id
,是的 #temp 表确实需要索引)original_test_dataset
是否以任何方式优化,因为缺少索引id
可能不是。declare @TableID varchar(20)
vs. [id] [varchar](50) NULL
:您正在默默地截断数据。基本上,您的脚本会破坏表格。