Sql 使用游标从现有数据集生成虚拟数据很慢
我试图从表中现有的数据生成虚拟数据。我只想将表1中的记录数增加到N个指定的数量。其他表应根据外键引用增加 这些表具有一对多关系。对于表1中的一条记录,我可以在表2中有多个条目,在表3中,我可以根据第二个表的ID有多条记录 由于ID是主键,我要么通过Sql 使用游标从现有数据集生成虚拟数据很慢,sql,sql-server,performance,sql-server-2016,Sql,Sql Server,Performance,Sql Server 2016,我试图从表中现有的数据生成虚拟数据。我只想将表1中的记录数增加到N个指定的数量。其他表应根据外键引用增加 这些表具有一对多关系。对于表1中的一条记录,我可以在表2中有多个条目,在表3中,我可以根据第二个表的ID有多条记录 由于ID是主键,我要么通过 SET @NEWLY_INSERTED_ID = SCOPE_IDENTITY() 插入到表1并在表2的insert中使用后,或将它们插入到temp表并将它们连接起来,以获得与表3相同的结果 这是我使用光标的方法 以上代码有效!它生成我需要的数据。
SET @NEWLY_INSERTED_ID = SCOPE_IDENTITY()
插入到表1并在表2的insert中使用后,或将它们插入到temp表并将它们连接起来,以获得与表3相同的结果
这是我使用光标的方法
以上代码有效!它生成我需要的数据。但是,它非常非常慢。只是做一些比较。表1的数据初始加载量约为60000条记录,表2为74000条记录,表3为3400条记录
我试图在表1中插入9000行。使用上述代码,需要17:05:01秒才能完成
关于如何优化查询以加快运行速度,有什么建议吗?我的目标是在表1中插入1-2百万条记录,而不必等待几天。我不受光标的束缚。我可以以任何其他可能的方式实现相同的结果。您只能使用while循环进行插入,不需要使用游标。您可以演示一个示例吗?
DECLARE @MyId as INT;
DECLARE @myCursor as CURSOR;
DECLARE @DESIRED_ROW_COUNT INT = 70000
DECLARE @ROWS_INSERTED INT = 0
DECLARE @CURRENT_ROW_COUNT INT = 0
DECLARE @NEWLY_INSERTED_ID INT
DECLARE @LANGUAGE_PAIR_IDS TABLE ( LangugePairId INT, NewId INT, SourceLanguage varchar(100), TargetLangauge varchar(100) )
WHILE (@ROWS_INSERTED < @DESIRED_ROW_COUNT)
BEGIN
SET @myCursor = CURSOR FOR
SELECT Id FROM MyTable
SET @CURRENT_ROW_COUNT = (SELECT COUNT(ID) FROM MyTable)
OPEN @myCursor;
FETCH NEXT FROM @myCursor INTO @MyId;
WHILE @@FETCH_STATUS = 0
BEGIN
IF ((@CURRENT_SUBMISSION_COUNT < @DESIRED_ROW_COUNT) AND (@ROWS_INSERTED < @DESIRED_ROW_COUNT))
BEGIN
INSERT INTO [dbo].[MyTable]
([Column1]
([Column2]
([Column3]
)
SELECT
,convert(numeric(9,0),rand() * 899999999) + 100000000
,COlumn2
,Colum3
FROM MyTable
WHERE Id = @MyId
SET @NEWLY_INSERTED_ID = SCOPE_IDENTITY()
INSERT INTO [dbo].[Language]
([MyTable1Id]
,[Target]
,[Source]
OUTPUT inserted.Id, inserted.MyTable1Id, inserted.Source, inserted.[Target] INTO @LANGUAGE_PAIR_IDS (LangugePairId, NewId, SourceLanguage, TargetLangauge)
SELECT
@NEWLY_INSERTED_ID
,[Target]
,[Source]
FROM [dbo].[Language]
WHERE MyTableId = @MyId
ORDER BY Id
DECLARE @tbl AS TABLE (newLanguageId INT, oldLanguageId INT, sourceLanguage VARCHAR(100), targetLanguage VARCHAR(100))
INSERT INTO @tbl (newLanguageId, oldLanguageId, sourceLanguage, targetLanguage)
SELECT 0, id, [Source], [Target] MyTable1Id FROM Language WHERE MyTable1Id = @MyId ORDER BY Id
UPDATE t
SET t.newlanguageid = lp.LangugePairId
FROM @tbl t
JOIN @LANGUAGE_PAIR_IDS lp
ON t.sourceLanguage = lp.SourceLanguage
AND t.targetLanguage = lp.TargetLangauge
INSERT INTO [dbo].[Manager]
([LanguagePairId]
,[UserId]
,[MyDate])
SELECT
tbl.newLanguageId
,p.[UserId]
,p.[MyDate]
FROM Manager m
INNER JOIN @tbl tbl
ON m.LanguagePairId = tbl.oldLanguageId
WHERE m.LanguagePairId in (SELECT Id FROM Language WHERE MyTable1Id = @MyId) -- returns the old language pair id
SET @ROWS_INSERTED += 1
SET @CURRENT_ROW_COUNT +=1
END
ELSE
BEGIN
PRINT 'REACHED EXIT'
SET @ROWS_INSERTED = @DESIRED_ROW_COUNT
BREAK
END
FETCH NEXT FROM @myCursor INTO @MyId;
END
CLOSE @myCursor
DEALLOCATE @myCursor
END