Sybase性能优化经验

经验一、where 条件左边最好不要使用函数,比如:

select … where datediff(day,date_column,getdate())>0
这样即使在date_column列上建立了索引,也可能不会使用索引,而使用全表扫描。
这样的语句要重新规划设计,保证不使用函数也能够实现。通过修改,一个系统过程的运行效率提高大约几十倍甚至上百倍!此外不要使用诸如like ‘%ab’,不能充分利用索引,而要在%前加字符。

经验二、两个比较字段最好使用相同数据类型,而不是兼容数据类型。比如 int 与 numeric(感觉一般不是太明显)。

经验三、复合索引的非前导列做条件时,基本没有起到索引的作用。
比如 create index idx_tablename_ab on tablename(a,b)
update tablename set c = XX where b>= XXX and …
在这个语句中,只用了索引列b而没用索引列a做查询条件,基本上索引没有发挥作用。 导致表扫描引起blocking 甚至运行十几分钟后报告失败。
一定要认真检查 改正措施: 在接口中附加条件
update tablename set c = XX where a = XXX and b>= XXX
或者建立索引类似于
create index idx_tablename_ba on tablename(b,a)

经验四、 多个大表的关联查询,如果性能不好,并且其中一个大表中取的数据比较少,可以考虑将查询分两步执行。
先将一个大表中的少部分数据 select * into #tmp from large_table where …
然后再用 #tmp 去做关联,效果可能会好不少。(前提:生成 #tmp表时,访问large_table 用到了比较好的索引,速度比较快)

经验五、 tempdb 的使用。
最好多用 select into ,这样不记日志 ,尤其是有大量数据的报表时。虽然写起来麻烦,但值得。
create table #tmp (……)这样写性能不好。尤其是大量使用时,容易发生tempdb 争用。

经验六、 系统级别的参数设置
一定要估计一下,不要配置太多,占用资源 ,配置太少,发生性能问题。
连接数,索引打开个数、锁个数 等、 当然 ,内存配置不要有明显的问题,比如,procedure cache
不够 (一般缺省20%,如果觉得太多,可以减少一些)。如果做报表经常使用大数据量读,可以考虑使用 16K data cache

阅读更多

Sybase:Specifying I/O Size in a Query

Specifying I/O Size in a Query

If your SQL Server is configured for large I/Os in the default data cache or in named data caches, the optimizer can decide to use large I/O for:

Queries that scan entire tables

Range queries using clustered indexes, such as queries using >, < , > x and < y, between, and like "charstring%" Queries that use covering nonclustered indexes In these cases, disk I/O can access up to eight pages simultaneously, if the cache used by the table or index is configured for it. Each named data cache can have several pools, each with a different I/O size. Specifying the I/O size in a query causes the I/O for that query to take place in the pool that is configured for that size. See Chapter 9, "Configuring Data Caches" in the System Administration Guide for information on configuring named data caches. To specify a particular I/O size, add the prefetch specification to the index clause of a select, delete, or update statement. The syntax is: select select_list from table_name (index index_name prefetch size) [, table_name ...] where ... delete from table_name (index index_name prefetch size) ... update table_name set col_name = value from table_name (index index_name prefetch size) ... Valid values for size are 2, 4, 8, and 16. If no pool of the specified size exists in the data cache used by the object, the optimizer chooses the best available size. If there is a clustered index on au_lname, this query performs 16K I/O while it scans the data pages: select * from authors (index au_names prefetch 16) where au_lname like "Sm%"

阅读更多

数据库存取缓冲区的LRU与MRU算法

数据库存取缓冲区的LRU与MRU算法

1.Cache Hit and Cache Miss

当使用者第一次向数据库发出查询数据的请求的时候,数据库会先在缓冲区中查找该数据,如果要访问的数据恰好已经在缓冲区中(我们称之为Cache Hit)那么就直接用缓冲区中读取该数据.

反之如果缓冲区中没有使用者要查询的数据那么这种情况称之为Cache Miss,在这种情况下数据库就会先从磁盘上读取使用者要的数据放入缓冲区,使用者再从缓冲区读取该数据.

很显然从感觉上来说Cache Hit会比Cache Miss时存取速度快.

2.LRU(最近最少使用算法) and MRU(最近最常使用算法)

所谓的LRU(Least recently used)算法的基本概念是当内存的剩余的可用空间不够时,缓冲区尽可能的先保留使用者最常使用的数据,换句话说就是优先清除”较不常使用的数据”,并释放其空间.之所以”较不常使用的数据”要用引号是因为这里判断所谓的较不常使用的标准是人为的、不严格的.所谓的MRU(Most recently used)算法的意义正好和LRU算法相反.

下面我们通过Oracle 9i Cache中对LRU和MRU的使用来看一下两者在缓冲区工作机制中的作用和区别

在Oracle 9i中有LRU List的概念我们可以把LRU List想象成是一连串的缓冲区集合,两端分别是LRU端和MRU端, 当数据库从磁盘上读取数据放入缓冲区时,系统必须先确定缓冲区中有free buffers,这个时候Oracle 9i会扫描LRU List,扫描的基本原则是

1. 从LRU端到MRU端;

2. 当扫描到free buffer或已扫描的缓冲区数目超过临界值时,就会停止扫描动作;

如果在扫描过程顺利的在LRU List中找到了free buffer,那么Oracle 9i就把从磁盘读出的数据写到free buffer中然后把free buffer加到LRU List的MRU端.

那如果扫描过程没有在LRU List中找到free buffer怎么办?当然是从LRU List的LRU端开始清除缓冲区,如此一来就可以腾出新的空间了.

下图就是一个例子

使用者查询数据A,初始的时候LRU List中没有数据A,于是Oracle 9i到磁盘读取A,然后放到LRU List的MRU端,使用者再从LRU List中读取数据A,同理对于B,C…当LRU List满了以后,如果使用者查询N,此时N不在LRU List中而且LRU List中已经没有free buffer了,此时Oracle 9i就开始从LRU端淘汰A以腾出空间存放N.

阅读更多

Sybase数据库大数据处理问题总结

最近在做大数据量清除的任务,从1亿条数据中删除3000条,怎么弄,直接delete,时间上不仅难以忍受,更容易造成日志空间溢出和死锁。另外,如果发生回滚,这将是灾难性的。

一种比较好的做法是利用rowcount分批进行删除。每次删除50W条左右即可,每次利用日志空间1G,然后就会做日志清理。至于为什么每次利用1G后做清理,跟两个东西有关。一个是trunc log on chkpt,另一个就是checkpoint。

trunc log on chkpt的意思就是系统在做checkpoint的时候进行日志截断清除。那么系统到底什么时候做checkpoint呢,只能从官网找了:

各位看官老爷请看下文吧,懒得翻译了:

Automatic checkpoint procedure

Approximately once a minute, the checkpoint task checks each database on the server to see how many records have been added to the transaction log since the last checkpoint. If the server estimates that the time required to recover these transactions is greater than the database’s recovery interval, Adaptive Server issues a checkpoint.

The modified pages are written from cache onto the database devices, and the checkpoint event is recorded in the transaction log. Then, the checkpoint task “sleeps” for another minute.

To see the checkpoint task, execute sp_who. The checkpoint task usually appears as “CHECKPOINT SLEEP” in the “cmd” column:

阅读更多

Sybase:bcp命令参考

SYBASE数据库方面BCP说明

  BCP是SYBASE公司提供专门用于数据库表一级数据备份的工具。

  一般存放在所安装的ASE或者Open Client 的BIN目录中。

  12版本以前的ASE,bcp存放目录为 $SYBASE/bin

  12版本(含12版本)以后存放目录为 $SYBASE/OCS-12_x/bin

  其中$SYBASE为SYBASE安装目录,12_x代表12.0、12.5版本,显示为12_0或者12_5

  可执行文件名称为bcp.EXE

参数列表如下

  (可用 bcp 得到)

  usage: bcp [[database_name.]owner.]table_name[:slice_number] {in | out} datafile

  [-m maxerrors] [-f formatfile] [-e errfile]

  [-F firstrow] [-L lastrow] [-b batchsize]

  [-n] [-c] [-t field_terminator] [-r row_terminator]

  [-U username] [-P password] [-I interfaces_file] [-S server]

  [-a display_charset] [-q datafile_charset] [-z language] [-v]

  [-A packet size] [-J client character set]

  [-T text or image size] [-E] [-g id_start_value] [-N] [-X]

  [-M LabelName LabelValue] [-labeled]

  [-K keytab_file] [-R remote_server_principal]

  [-V [security_options]] [-Z security_mechanism] [-Q]

阅读更多

Sybase锁机制以及死锁避免详解[转载]

在数据库实现中,通过锁定机制控制数据库的并发访问,保证数据库访问的正确性。根据定义:

  锁定是一种并发控制机制:它可以确保数据在同一事务中和不同事务之间保持一致。在多用户环境中,由于几个用户可能会在同一时间使用同一数据,因此需要锁定功能。

  sybase锁分类

  按照锁性质可以分为共享锁,排他锁。当在数据库事务中,读取信息时,会对数据库添加共享锁。当修改信息时,会添加排他锁。

  按照锁的粒度,可以分为行锁,页锁,表锁等。

  sybase隔离级别

  sybase分为0,1,2,3四个隔离级别。

  0 读取未提交的,允许事务读取未提交的数据更改,排他锁在对数据库进行写操作后立即释放,不会持有到事务提交或回滚。

  1 读取已提交的,仅允许事务读取已提交的数据更改,排他锁持有到事务提交或回滚,但共享锁在加载数据到内存后立即释放。

  2 可重复读取事务可重复同一查询,事务读取过的任何行都不会被更新或删除,排它锁和共享锁都会持有到事务结束,查询结果集不可以删除和修改,但是可以插入。

  3 可串行化读取事务可重复同一查询,且得到完全相同的结果。不能插入任何将出现在结果集中的行,排它锁和共享锁都会持有到事务结束,查询结果集不可以增删改。

  可以使用select @@isolation语句查看数据库的隔离级别。

  sybase数据库通常隔离界别设置为1,值得注意的是使用WAS通过jdbc连接数据库上,经常会将隔离级别提升为2。在使用E-SQL编译时,通常将隔离级别提升为3。

阅读更多

Sybase 数据库锁

所支持的加锁机制

全页加锁

全页加锁既是一个新术语,它又是由ASE(Adaptive Server Enterprise)在过去所支持的一种加锁类型。这种类型有下列特性:对所有可被访问的页面在页面级加锁;

当各种类型的页面以任何方式发生改变时,对这些排它性的页面进行加锁;而且这种加锁机制一直保持到该事务终止;

当下一个所需的页面已经成功地获得,对那些已经释放的的当前访问页进行共享页面加锁(如果采用了第三层ANSI隔离,则把这种加锁机制保持到该事务终止为止) 。采用页级时间印记(timestamp)以确定是否发生改变,详细信息记录在事务日志中,以便在系统恢复时以向前或向后方式使用。

这种加锁方式常常提供性能最高的解决方案,特别是当应用设计时已经考虑了这些特性时更是如此。但是,有一些应用系统,当发生某些活动时,这种对整个页面进行加锁的方式就可能会对系统性能产生有重大意义的影响。对于那些面对诸如文件系统或其它已经支持更细小尺度加锁机制的数据库厂家产品的一般环境而设计的应用系统而言,这种情况尤其如此。

阅读更多

记录某段简单SQL执行缓慢的解决过程

虽没有真正明白,记录一遍以后查看。

在工作过程中遇到一个很奇怪的问题。

两个表左连接查询,左表9w数据量,右表3w数据量,连接条件是右表的两个主键。

select count(*) from

AAA left join BBB

on AAA.f_prov = BBB.f_prov and AAA.f_sqbrno = BBB.f_brno

where …..

GROUP BY AAA.f_prov,f_aucnno,f_sqbrno,f_name

其他类似的查询基本都是2s左右,但是这两个表查询实际会用24s的时间来进行。

然后用执行计划进行查看,发现其他表连接用的是Nested Loop Join,而这个用的是Merge Join。然后我发现第二个表进行了排序并且没有命中索引和主键。

解决方法是删除之前BBB表的两个索引,重新建立BBB表的唯一索引,把f_prov和f_brno加入索引中,虽然还是Merge Join,但是基本上都在2s一下。

有机会要看一下怎么设定数据库使用哪种JOIN算法。

阅读更多

  • © 2011 知研片语
  • 京ICP备16042882号