用 游标 插入数据太慢 怎么办

Joson.e8love 2012-09-21 12:32:49
用 游标 插入数据太慢 怎么办

用游标合并表生成 新表

插入过程中用到 自定义函数





...全文
255 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Joson.e8love 2012-09-21
  • 打赏
  • 举报
回复
应该没什么问题吧 是不是 插入过程中使用了自定义函数 导致

现在要处理数据 大约18万条

已经插入数据 一万多点 用了一个小时了

有点郁闷 肯定是有问题的 怎么处理下?
Joson.e8love 2012-09-21
  • 打赏
  • 举报
回复




DECLARE @WineID Char(36),@AreaID Char(36),@ChateauID Char(36)
,@wineVarietyID char(36),@Names NVARCHAR(100);



Declare @WineVarietyEn nvarchar(50), @WineVarietyCn nvarchar(50)

Declare @AliasCn nvarchar(max), @AliasEn nvarchar(max),@AliasCnCount int,@AliasEnCount int

Declare @GrapeEnName nvarchar(max), @GrapeCnName nvarchar(max), @GrapeCount int

Declare @ChateauCn nvarchar(max), @ChateauEn nvarchar(max)
Declare @AreaCn nvarchar(max), @AreaEn nvarchar(max)



Delete FROM LucenIndexTab;


BEGIN
--定义游标.
DECLARE WineCursor CURSOR FOR

Select ID,Names,AreaID,ChateauID,wineVarietyID
From WineIndexs Order by hitcount --

--where ID='E4907C1D-699F-48A8-9B86-45EB652FDB96'

--FOR UPDATE;
--打开游标.
OPEN WineCursor;


--填充数据.
FETCH NEXT FROM WineCursor INTO @WineID,@Names,@AreaID,@ChateauID,@wineVarietyID;
--假如检索到了数据,才处理.
WHILE @@fetch_status = 0

BEGIN

PRINT '+++++++++++++++++++++++++++++++++++++++++++++++++++++';
PRINT @WineID+'名称:'+@Names;
PRINT '+++++++++++++++++++++++++++++++++++++++++++++++++++++';


--更新数据.
-- UPDATE
-- WineIndexs
-- SET
-- Names = Names + '更新'
--
-- WHERE
-- CURRENT OF WineCursor;

-- 填充下一条数据.

-- 创建数据库

----下边是使用自定义函数部分

---酒种类
set @WineVarietyEn=(select [foreignName] from GetWineVarietyEn(@wineVarietyID));
set @WineVarietyCn=(select [chineseName] from GetWineVarietyCn(@wineVarietyID));

--别名
set @AliasCn=(select Alias from GetUnionAliasTab(@WineID,1));
set @AliasEn=(select Alias from GetUnionAliasTab(@WineID,0));
set @AliasCnCount=(select AliasCount from GetUnionAliasTab(@WineID,1));
set @AliasEnCount=(select AliasCount from GetUnionAliasTab(@WineID,0));




--葡萄种类
set @GrapeEnName=(select GrapeName from GetUnionGrapeTab(@WineID,0));
set @GrapeCnName=(select GrapeName from GetUnionGrapeTab(@WineID,1));
set @GrapeCount=(select GrapeCount from GetUnionGrapeTab(@WineID,0));

-- 酒庄名称
set @ChateauEn=(select [foreignName] from GetChateauEn(@ChateauID));
set @ChateauCn=(select * from GetChateauCn(@ChateauID));


-- 产区名称
set @AreaCn=(select [chineseName] from GetAreaCn(@AreaID));
set @AreaEn=(select [foreignName] from GetAreaEn(@AreaID));

----结束使用自定义函数部分


---插入数据到新表(LucenIndexTab)

insert into LucenIndexTab select *

,@WineVarietyEn,@WineVarietyCn,@AliasCn,@AliasEn,@AliasCnCount,@AliasEnCount

,@GrapeEnName,@GrapeCnName,@GrapeCount,@ChateauEn,@ChateauCn

,@AreaEn,@AreaCn

from WineIndexs where ID=@WineID


print '中文别名:'+@AliasCn
print 'e文别名:'+@AliasEn
PRINT '----------------------------------------------------';

print '葡萄中文名:'+@GrapeEnName
print '葡萄e文名:'+@GrapeCnName

PRINT '----------------------------------------------------';

print '产区中文名:'+@AreaCn
print '产区e文名:'+@AreaEn


FETCH NEXT FROM WineCursor INTO @WineID,@Names,@AreaID,@ChateauID,@wineVarietyID;

END;

--关闭游标
CLOSE WineCursor;
--释放游标.
DEALLOCATE WineCursor;

END;

Go







DBA_磊仔 2012-09-21
  • 打赏
  • 举报
回复
DML操作尽量不使用游标吧,使用集合的方法操作
人生无悔 2012-09-21
  • 打赏
  • 举报
回复
拼結好sql語句後,直接動態執行就好了

提供下你的表結構及要求插入數據的方式
DBA_磊仔 2012-09-21
  • 打赏
  • 举报
回复
整个数据库都可以不用游标,要不要那么快否定先,用游标,想优化太难
Joson.e8love 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

引用 10 楼 的回复:
不可以 有一对多的关系 而且 一对多这个多要变成一列 我自定义函数里边做这样处理了

比如 一个 wineID 可以对应多个 GrpeID 类似的

可以的,这个需求SQL2005以上可实现,TSQL技巧而已.
[/Quote]

已经从程序方面去考虑了 谢谢 \(^o^)/~

唐诗三百首 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
不可以 有一对多的关系 而且 一对多这个多要变成一列 我自定义函数里边做这样处理了

比如 一个 wineID 可以对应多个 GrpeID 类似的
[/Quote]
可以的,这个需求SQL2005以上可实现,TSQL技巧而已.
Joson.e8love 2012-09-21
  • 打赏
  • 举报
回复
视图很难做的 也许是我没弄好 游标

其实其中 查询 函数 用的也是视图 应该是这样个原因 如果是基表查询或许能比现在快点
Joson.e8love 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

从代码看,可以不用游标方式的,
函数可以转为outer apply..的写法
子查询可以转为left join..的写法
[/Quote]

不可以 有一对多的关系 而且 一对多这个多要变成一列 我自定义函数里边做这样处理了

比如 一个 wineID 可以对应多个 GrpeID 类似的
唐诗三百首 2012-09-21
  • 打赏
  • 举报
回复
从代码看,可以不用游标方式的,
函数可以转为outer apply..的写法
子查询可以转为left join..的写法
Joson.e8love 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

你其实要去研究你的数据,我举个例子,如果你是从A表去数据,然后对字段a调用函数f,那你可以使用:
insert into 目标表
select f(a),....
from A

这样就可以拉,没必要用游标甚至循环。
上述只是例子,有点.....别见怪。
[/Quote]

我要从 A表取出字段 然后 用取出字段做参数 执行函数 不用游标可以?
發糞塗牆 2012-09-21
  • 打赏
  • 举报
回复
你其实要去研究你的数据,我举个例子,如果你是从A表去数据,然后对字段a调用函数f,那你可以使用:
insert into 目标表
select f(a),....
from A

这样就可以拉,没必要用游标甚至循环。
上述只是例子,有点.....别见怪。
Joson.e8love 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

用游标插入数据是最低效的....我相信一定还有其他方法实现集合操作。
[/Quote]

是的 \(^o^)/~
發糞塗牆 2012-09-21
  • 打赏
  • 举报
回复
用游标插入数据是最低效的....我相信一定还有其他方法实现集合操作。

22,301

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧