2009年4月1日星期三

如何扩展sybase数据库TEMPDB大小(转)

用sp_helpdb tempdb看了一下,原来的安装人员安装时master只有3M,tempdb在master设备上,只有1M多点,怪不得一个order就出问题。
解决的方法:
首先获取vdevno
use master
go
select max(convert(tinyint,substring(convert(binary(4),d.low),v.low,1)))+1
from master.dbo.sysdevices d,master.dbo.spt_values v
where v.type='E'and v.number=3
go
这里得到6
然后创建一个tempdb_dev设备:
disk init name="tempdb_dev", physname="d:\sybase\data\tempdb.dat", vdevno=6, size=262144
这里size是设备尺寸,单位是2K,一个页面2K,共创建500M的设备
接着扩展tempdb
alter database tempdb on tempdb_dev=500

2009年3月31日星期二

sybase分页查询思路

CREATE PROCEDURE GetDataByPage(
@SqlStr varchar(8000),
@PageSize int,
@CurrentPage int)
AS
DECLARE @FirstRec int, @LastRec int,@dt varchar(10)
BEGIN

SELECT @FirstRec = (@CurrentPage - 1) * @PageSize
SELECT @LastRec = (@CurrentPage * @PageSize + 1)

SELECT @dt= substring(convert(varchar,rand()),3,10)

SELECT @SqlStr = stuff(@SqlStr,charindex(' FROM ',upper(@SqlStr)),6,' INTO tempdb..Paging'+@dt+' FROM ')
EXECUTE (@SqlStr)

SELECT @SqlStr = 'ALTER TABLE tempdb..Paging'+@dt+' ADD RID numeric(10) IDENTITY PRIMARY KEY'
EXECUTE (@SqlStr)

SELECT @SqlStr = 'SELECT Count(*) From tempdb..Paging'+@dt
EXECUTE (@SqlStr)

SELECT @SqlStr = 'SELECT * FROM tempdb..Paging'+@dt+' WHERE RID >; '+convert(varchar,@FirstRec)+' and RID < '+convert(varchar,@LastRec)
EXECUTE (@SqlStr)

SELECT @SqlStr = 'DROP TABLE tempdb..Paging'+@dt
EXECUTE (@SqlStr)

END


另外一个小数据量时的简便方法:
select rowid=identity(12), * into #temptable1 from salesdetail
select * from #temptable1 where rowid<10>=1
注:当大数据量时将全表数据复制到临时表中是效率低下的

sybase中的临时表当用select into #table的形式时,是不记录日志的。速度非常快。
这点和oracle不同。算是sybase的一个feature.

用游标更好一些。
用临时表算法的空间复杂度是O(n),如果表很大或没有预存在Cache中,所用的I/O时间就非常可观了。
用游标定位到指定的页,空间复杂度应该是O(1),虽然游标遍历记录比直接用Select稍慢一点,但考虑到分页应用中,每次只读取一页的内容,所以这个时间性能上的损失可以忽略。


set rowcount 20
select * from salesdetail
set rowcount 0
注:此种方式不能设定查询的条件,如起始和结束位置、不能first、top、start at等。

一个简单的分页的存储过程:
create procedure test_p @ipage int, @num int as /* @ipage 页码, @num 每页的记录数 */
begin
declare @maxpages int, @rcount int /* @maxpages 最大页码 */
if @ipage>=100
select @maxpages=ceiling(count(*)/@num) from test
else
select @maxpages=100000
if @ipage<=@maxpages/2
begin
select @rcount=@ipage*@num
set rowcount @rcount
select id=identity(12),name,descs,ddd into #temptable1 from test order by id
select * from #temptable1 where id>(@ipage-1)*@num and id<= @ipage*@num
end else
begin
select @rcount=(@maxpages-@ipage+1)*@num
set rowcount @rcount
select id=identity(12),name,descs,ddd into #temptable2 from test order by id desc
select id,name, ddd,descs from #temptable2 where id>(@maxpages-@ipage)*@num and id<= (@maxpages-@ipage+1)*@num order by id desc
end
end

此存储过程的问题是:select into #temptable1需要大量的数据空间(tempdb),同时也会增加时间。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
版本更新:1.0.2
注意程序最后要加上set rowcount 0

create procedure splitpage @qry varchar(16384),@ipage int, @num int,@maxpages int = 5000 as
/*@qry SQL语句, @ipage 页数, @num 每页记录条数, @maxpages 最大查询页数 */
begin

declare @rcount int
declare @execsql varchar(16384)

if @ipage > @maxpages
begin
select '输入页数[' || convert(varchar,@ipage) || ']大于最大查询页数[' || convert (varchar,@maxpages) ||']'
return
end

select @rcount=@ipage*@num
set rowcount @rcount
set @execsql = stuff(@qry,charindex('select',@qry),6,'select sybid=identity(12),')
set @execsql = stuff(@execsql, charindex('from',@execsql),4,'into #temptable1 from')
set @execsql = @execsql || ' select * from #temptable1 where sybid>' || convert(varchar,(@ipage-1)*@num) || ' and sybid <= ' || convert(varchar,@ipage*@num)
execute (@execsql)
set rowcount 0
end

2009年3月12日星期四

网络小说推荐

1. 英雄志
2. 天行健
3. 北京战争
4. 乱世激流
5. 银河英雄传说
6. 昆仑(作者:风歌)
7. 君与臣
8. 新宋
9. 紫川
10. 风姿物语
11. 诛仙
12. 偷天换日
13. 洛阳女儿行
14. 乱世铜炉
15. 泰坦苍穹下
16. 镜(墨香、拜月教之战、神之右手、六合书)
17. 此间的少年
18. 武林客栈
19. 神授的权杖
20. 猎命师传奇(作者:九把刀)
21. 太虚幻境
22. 球状闪电(作者:刘慈欣)
23. 乡村教师
24. 九州—缥缈录(作者:江南)
25. 朱雀记(作者:猫腻)
26. 基地(作者:阿西莫夫)
27. 亵渎(作者:烟雨江南)
28. 随波逐流之一代军师(作者:风歌)
29. 庆余年
30. 三体(作者:刘慈欣)
31. 若星汉
32. 莽荒岁月
33. 异人傲世录
34. 帝国时代的士兵
35. 秋林箭(作者:斩鞍)
36. 冰与火之歌.权力的游戏(作者:乔治.马丁,重庆出版社版本,谭光磊翻译)
37. 尘劫录
38. 商博良
39. 赫氏门徒
40. 大亨传说(有关香港电影历史)
41. 长安古意
42. 都市妖奇谈
43. 汉风 (作者:克劳塞维茨)
44. 月落
45. 风起紫罗峡
46. 汉末浮生记
47. 杯雪

2009年2月26日星期四

The key points for memory configuration

The key points for memeory configuration

1. 系统管理员需要决定ASE可以使用的内存总量,并设置'max memory'值;
2. 在系统启动时和系统运行时都可以通过设置'allocate max shared memory'值将ASE使用的内存动态收集到'max memory'大小;在某些系统上过大的shared memory segments会对系统表现造成不利影响,需要了解系统平台相关文档以决定'max memory'大小;
3. 配置其他影响内存分配的配置参数;
4. 'max memory'和'total logic memory'之间的差值可以用于procedure cache和data cache或者其他配置参数。
5. 当处理大字符串的数据查询时,ASE并不是静态的将数据缓冲分配到最大值,而是进行动态的分配。当有需要时,它将把buffer扩充到最大值,而不论其是否需要。这会造成处理大字符串查询时ASE系统性能有一个边际损失;
6. 一个表数据行超过1000列或者1个存储过程参数超过10000个,那么ASE需要为内部数据结构分配更多的内存。一些小任务的增加将会造成ASE性能表现的下降;
7. 动态的分配内存将会对ASE系统有轻微影响;
8. 当使用较大的logic page size时,每次ASE从硬盘获取与logic page size同样大小的数据块,这样会增加I/O吞吐量。

2009年2月25日星期三

Sybase ASE12.5内存配置(2)

ASE如何分配内存

1. logic page size
所有的数据库及数据库中的对象都采用同样的logic page size,logic page size在安装ASE时指定,可选项有2,4,8和16K。allocation page,object allocation map(OAM) page,data page,index page,text page等都建立在logic page之上。更大的logic page size值可以使你能创建更大的row,同时也可以使数据库读取数据时的效率更高,因为每一页更大,所包含的数据也更多。
logic page size是一个服务设定值,你无法对单个数据库进行单独设置,同时数据库中的每一行也不能存在于多个页之上。
extent: 数据库为对象分配空间时使用extent,每一个extent相当于8个logic page size大小。
更大的logic page size值也使得一些小的表的空间的最后一页所剩余的空间也更大。
数据库根据logic page size 不同,需要的最小磁盘空间数也不同,见下表:
2K 2MB
4K 4MB
8K 8MB
16K 16MB
内存分配的配置参数与logic page size不尽相同,无论logic page size设置多大,绝大多数内存分配参数采用2K,其中包括一下几个重要的内存配置参数:

2. 磁盘空间分配
磁盘空间分配以2K为单位。
3. logic page size不是默认时的处理
当logic page size设置为2K时,default data cache默认是8M大小,等于2048 buffers,而logic page size是16k时,如果仍然采用8M的default data cache,则只有256 buffers。如果buffer数量过小,在一个忙碌的系统中,buffers总是处于重写过程中,会导致系统整个运行速度变慢。所以当logic page size是默认的4倍时,你也需要将default data cache也设为默认的4倍。
4. Heap memory
Heap memory
是在启动时即已确定,用于当用户任务所耗堆内存过大时动态分配heap memory给用户任务使用,用户任务完成后将归还给heap memory。这样,可以减少预先设定给用户任务(user connections, worker processes)的堆内存,同时提高效率。
配置参数是heap memory per user, sp_configure 'heap memory per user',***(amount_of_memory),单位是byte,默认是4096bytes。
sp_configure 'heap memory per user', 10 给10个用户连接分配默认heap memory。
sp_configure 'heap memory per user', 0, "4K" 给每个用户分配4k的heap memory。
ASE初始化分配给heap memory总量是1M,不包括在刚才指定分配的内存中。初始的heap memory将会用于所有的user connections和worker processes。所以,以下两个参数与heap memory的分配密切相关:
number of user connections
number of worker processes
查看现有heap memory size使用命令:select @@heapmemsize
4.1. 计算ASE设置的heap memory size
((1024 * 1024) + (heap memory in bytes)* (number of user connections + number of worker processes) )
For example, if your server is configured for:
* heap memory per user : 4K
* number of user connectins : 25 (the default)
* number of worker processes : 25 (the default)
@@heapmemsize reports 1378304 bytes.
And the estimated value using the formula above, is:
((1024 X 1024) + (4 * 1024 * 50)) = 1253376
Now, if you increase the number of user connections, the size of the heap memory pool increases accordingly:
sp_configure 'user connections', 100
@@heapmemsize reports 1716224 bytes.
The estimated value in this case comes out to be:
((1024 * 1024) + (4 * 1024 * (100 + 25) ) = 1560576



5.

Sybase ASE内存分配(1)

今天同事为ASE分配内存后出现ASE服务无法启动的情况,观察ASE的errorlog发现报“os_create_region: Failed to get virtual memory information.”,确定是因为内存配置不合理造成的。通过google发现解决问题办法,如下:
修改$servername$.cfg
[Named Cache:default data cache]

cache size = DEFAULT

cache status = default data cache

cache replacement policy = DEFAULT

local cache partition number = D
EFAULT
修改cache size = DEFAULT

然后重新配置

没有修改ASE启动时的默认配置文件$servername$.cfg,而是将修改之前的ASE配置文件备份(如$servername$.033之类)修改名称替换掉当前不正确的cfg配置文件,重新启动后ASE恢复正常。

思考ASE启动失败的原因,在Sybase的《系统管理员教程》中,《14. 配置内存》中讲到如果ASE不能得到配置的内存,就可能无法启动。
那么如何正确的分配内存呢?
1. 确定计算机总的物流内存;
2. 从总的物流内存中减去操作系统和其他必备服务、软件所占用的内存;
3. 减去backup server 、Monitor Server和其他与ASE Server相关软件所耗用的内存;
4. 如果计算机非ASE专用,减去其他系统所需内存;比如X-window等客户应用程序;
5. 减去分配给additional network memory配置参数的任何内存;
剩下的内存即是ASE可用的总内存,可参考此值设置total memory的值。
我认为一个比较简便的方法是不启动ASE,而将Backup Server和Monitor Server以及其他必备服务、程序启动起来,观察计算机所剩内存,由此确定Total Memory。

当遇到以下情况时应该考虑修改total memory值:
1. 计算机RAM数量改变时;
2. 当计算机使用模式改变时;(不太明白?)
3. 如果为ASE的 addtional network memory分配了内存。

下图是Sybase ASE内存分配示意图。





















其中,过程高速缓存和数据高速缓存根据procedure cache percent进行分配。
在12.5版本中,sybase内存分配有所区别,请见图

2009年2月24日星期二

如何修改Syabse服务器端的默认字符集

如何修改Syabse服务器端的默认字符集
来源: 赛迪网 日期:2008-11-07 我要评论
在安装完Sybase后,很多人在使用isql或程序插入中文数据后发现,查询出的数据是乱码(中文字符全为?),这是因为客户端的字符集和服务端的字符集不一致造成的,Sybase默认安装后默认字符集为:iso_1。通常使用中文字符集在Sybase内是cp936。那么如何设置Sybase的字符
在安装完Sybase后,很多人在使用isql或程序插入中文数据后发现,查询出的数据是乱码(中文字符全为‘?’),这是因为客户端的字符集和服务端的字符集不一致造成的,Sybase默认安装后默认字符集为:iso_1。通常使用中文字符集在Sybase内是cp936。那么如何设置Sybase的字符集呢?修改方法如下:

以Windows操作系统Sybase15为例:

首先说明察看服务端字符集和客户端字符集的方法:

查看服务器端字符集:

在isql环境中执行:

1>; sp_helpsort

2>; go

查看客户端字符集:

在isql环境中执行:

1>; select @@client_csname

2>; go

修改服务端字符集方法:

假设sybase安装目录为$sybase$

◆1.转到$sybase$\ASE-15_0\bin目录

执行命令:charset -Usa -P binary.srt cp936

◆2.打开isql,执行下面的SQL查询出cp936对应的id

select id , name from syscharsets where name = 'cp936'

go

假设查询结果为171

执行下面语句设定默认字符集

sp_configure 'default char',171 --可能有误,以上面的查询结果为准

go

关闭ASE

shutdown

go

◆3.重新启动sybase服务两次(第一次启动会失败),启动服务。