现象:
现在做一个程序,对数据库的几个装有大量数据的表进行操作,对其中的一个表进行
循环操作,以处理其他的几个表。其中用到了几个query,update,当程序跑的过程中,
SQLSERVER的内存不断的增长,跑完后关闭程序退出后也不降下来。
解决:
这是SQL的内存管理机制决定的,SQL管理内存的原则是这样的,只要你的内存够用(这个够用是指你分配给SQL的可用内存),则SQL不会释放占用的内存,新的操作会分配新的内存,直到分配完可用的内存后,才会释放内存,因为内存占用会一直上涨,直到达到极限
解决的方法是限制给SQL的可用内存量
另外,对于频繁操作数据库的操作,不要每一次都去getConnection,然后再close,这样是很消耗内存的,sql server的内存会持续增长,即使每次都对connection做了close,sql server的内存还是会不停增长,虽然sql server会自动调节,不会让系统死掉,但是内存太少,做任何操作都会变的很慢了。可行的办法是,对于频繁的数据库操作,根据执行的类型,比如按select、update、insert来分类,在内存中建立staitc Connection,让这些频繁的操作,也就是说减少Connection的建立数量,这样就会大幅度的降低内存的消耗量,内存几乎不增长了,问题就解决了。 ......
1.建表(Create table)时使用 IDENTITY (SEED,INCREMENT)
其中SEED是起始值,INCREMENT是增量。
例:
CREATE TABLE mytable1
(
[user_id] BIGINT NOT NULL
IDENTITY(1, 1) ,
[user_mail] NVARCHAR(255)
)
命令已成功完成。
2.修改表(Alter table)列的自增长
SQLServer不允许修改已经存储的自增长列,但是可以为一个没有自增长标识列的表添加自增长列
例:
DROP TABLE mytable1 -- 删除刚才创建的表
CREATE TABLE mytable1
(
[user_mail] NVARCHAR(255)
)
ALTER TABLE mytable1 ADD [user_id] BIGINT IDENTITY(1,1)
命令已成功完成。
3.手动插入自增长字段的值
例:
SET IDENTITY_INSERT mytable1 ON -- 开启 手动
INSERT INTO mytable1
( [user_id], [user_mail] )
VALUES ( 10, N'oyi319@email.com' )
SET IDENTITY_INS ......
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
create function [dbo].[split](@str nvarchar(1000),@word varchar(5),@no
int) returns nvarchar(500)
as begin
declare @len int
declare @index int
set @index=charindex(@word,@str)
set @index=len(@word)+@index-1
set @len=len(@str)
if @index >0 and @no=2
return substring(@str,@index+1,@len)
else if @index>0 and @no=1
return substring(@str,0,@index-len(@word)+1)
return @str
end ......
代码如下:
DECLARE
@TempTable table(UserID int , UserName nvarchar(50));
insert into
@TempTable (UserID,UserName) values (1,'a')
insert into @TempTable
(UserID,UserName) values (2,'b')
select UserID,UserName
from @TempTable FOR XML PATH
运行这段脚本,将生成如下结果:
复制代码
代码如下:
<row>
<UserID>1</UserID>
<UserName>a</UserName>
</row>
<row>
<UserID>2</UserID>
<UserName>b</UserName>
</row>
大家可以看到两行数据生成了两个节点,修改一下PATH的参数:
select
UserID,UserName from @TempTable FOR XML PATH('lzy')
再次运行上述脚本,将生成如下的
结果:
复制代码
代码如下:
<lzy>
<UserID>1</UserID>
<UserName>a</UserName>
</lzy>
<lzy>
<UserID>2</UserID>
<UserName>b</UserName>
</lzy>
可以看到节点变成,其实PATH()
括号内的参数是控制节点名称的,这样的话大家可以看一下 ......
代码如下:
DECLARE
@TempTable table(UserID int , UserName nvarchar(50));
insert into
@TempTable (UserID,UserName) values (1,'a')
insert into @TempTable
(UserID,UserName) values (2,'b')
select UserID,UserName
from @TempTable FOR XML PATH
运行这段脚本,将生成如下结果:
复制代码
代码如下:
<row>
<UserID>1</UserID>
<UserName>a</UserName>
</row>
<row>
<UserID>2</UserID>
<UserName>b</UserName>
</row>
大家可以看到两行数据生成了两个节点,修改一下PATH的参数:
select
UserID,UserName from @TempTable FOR XML PATH('lzy')
再次运行上述脚本,将生成如下的
结果:
复制代码
代码如下:
<lzy>
<UserID>1</UserID>
<UserName>a</UserName>
</lzy>
<lzy>
<UserID>2</UserID>
<UserName>b</UserName>
</lzy>
可以看到节点变成,其实PATH()
括号内的参数是控制节点名称的,这样的话大家可以看一下 ......
分页存储过程
sp_QueryPaging
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
-- =============================================
-- Author:
-- Create date:
-- Description: 分页查询
-- 返回的数据中总是在每条记录前加上行号RowNumber列。
-- 如果未指定@StrSelect参数,相当于设置它为'*'
-- 如果未指定@Strfrom参数,不做查询,返回-1
-- 如果未指定@StrWhere参数,则忽略Where条件
-- 如果未指定@StrOrder参数,试着自动获得标识列作为@StrOrder,失败则不做查询,返回-1
-- 如果未指定@PageSize参数,或者它<=0,则返回全部记录
-- 如果未指定@PageIndex参数,会设置它为1,显示第一页数据
-- 参考:shiwenbin http://www.cnblogs.com/virusswb/archive/2009/10/20/1587179.html
-- =============================================
ALTER PROCEDURE [dbo].[sp_QueryPaging]
@StrSelect NVARCHAR(4000) = '*' , --欲显示的列(多列用逗号分开),例如:id,name
@Strfrom NVARCHAR(4000) , --表名称,或者是表连接字符串,多表连接例如:student as s inner join dwinfo as dw on s.dwbh=dw.bh
@StrWhere NVARCHAR(400 ......
1.oracle环境
create table test
(
id number(4),
name varchar2(20)
)
在一个session中
insert into test values(1,'aa');
在另一个session中
select * from test1;
查询没被阻塞
2.sqlserver环境
在一个session中
insert into test values(1,'aa');
在另一个session中
select * from test1;
查询被阻塞(实际上前一个session在update或delete时均会阻塞本次查询,当然,如果加上with (nolock),也不会被阻塞) ......
1.oracle环境
create table test
(
id number(4),
name varchar2(20)
)
在一个session中
insert into test values(1,'aa');
在另一个session中
select * from test1;
查询没被阻塞
2.sqlserver环境
在一个session中
insert into test values(1,'aa');
在另一个session中
select * from test1;
查询被阻塞(实际上前一个session在update或delete时均会阻塞本次查询,当然,如果加上with (nolock),也不会被阻塞) ......