数据库设计优化经验谈

  慎用游标(Cursor) 

  游标提供了对特定集合中逐行扫描的手段,一般使用游标来逐行遍历数据,根据取出数据条件的不同进行不同的操作。而对于多表和大表中定义的游标(大的数据集合)循环很容易使程序进入一个漫长的等待甚至死机,笔者在某市“住房公积金管理系统”进行日终账户滚积数计息处理时,对一个10万个账户的游标处理时导致程序进入了一个无限期的等待(后经测算需48小时才能完成)(硬件环境:Alpha/4000 128MB RAM ,SCO Unix ,Sybase 11.0)。经修改程序并改用UPDATE语句后,该处理过程得以在20分钟之内完成。示例如下:

  Declare Mycursor cursor for select count—no from COUNT

  Open Mycursor

  Fetch Mycursor into @vcount—no

  While (@@sqlstatus=0)

  Begin

  If @vcount—no=′ ′ 条件1

操作1

  If @vcount—no=′ ′ 条件2

操作2

...

  Fetch Mycursor into @vcount—no

  End

    ...

  改为

  Update COUNT set 操作1 for 条件1

  Update COUNT set 操作2 for 条件2

...

  在某些必须使用游标的场合,可考虑将符合条件的数据行转入临时表中,再对临时表定义游标进行操作,这样,可使性能得到明显提高。笔者在某地市“电信收费系统”数据库后台程序设计中,对一个表(3万行中符合条件的30多行数据)进行游标操作(硬件环境:PC服务器,PⅡ266 64MB RAM ,Windows NT4.0 MS SQL Server 6.5)。

  示例如下:

Create #tmp /* 定义临时表 */

    ( 字段1

     字段2

      ... )

  Insert into #tmp select * from TOTAL where 条件

  Declare Mycursor cursor for select * from #tmp /*对临时表定义游标*/

    ...

  索引(Index)的使用技巧 

  创建索引一般有两个目的:维护被索引列的惟一性和提供快速访问表中数据的策略。大型数据库有两种索引,即簇索引和非簇索引,一个没有簇索引的表是按堆结构存储数据,所有的数据均添加在表的尾部;而建立了簇索引的表,其数据在物理上会按照簇索引键的顺序存储,一个表只允许有一个簇索引,因此,根据B树结构,可以理解添加任何一种索引均能提高按索引列查询的速度,但与此同时会降低插入、更新、删除操作的性能,尤其是当填充因子(Fill Factor)较大时。所以对索引较多的表进行频繁的插入、更新、删除操作时,建表和索引时应设置较小的填充因子,以便在各数据页中留下较多的自由空间,减少页分割及重新组织的工作。

  数据的一致性和完整性 

  为了保证数据库的一致性和完整性,设计人员往往会设计过多的表间关联(Relation),尽可能地降低数据冗余。表间关联是一种强制性措施,建立后,对父表(Parent Table)和子表(Child Table)的插入、更新、删除操作均要占用系统的开销,另外,最好不要用Identify 属性字段作为主键与子表关联。如果数据冗余低,数据的完整性容易得到保证,但增加了表间连接查询的操作。为了提高系统的响应时间,合理的数据冗余也是必要的。使用规则(Rule)和约束(Check)来防止系统操作人员误输入造成数据的错误是,设计人员的另一种常用手段,但是,不必要的规则和约束也会占用系统的不必要开销,需要注意的是,约束对数据的有效性验证要比规则快。所有这些,设计人员在设计阶段应根据系统操作的类型、频度加以均衡考虑。

  事务的陷阱 

  事务是在一次性完成的一组操作。虽然这些操作是单个的操作,SQL Server能够保证这组操作要么全部都完成,要么一点儿都不做。正是大型数据库的这一特性,使得数据的完整性得到了极大的保证。

  众所周知,SQL Server为每个独立的SQL语句都提供了隐含的事务控制,使得每个DML的数据操作得以完整提交或回滚,但是SQL Server还提供了显式事务控制语句,如:

  BEGIN TRANSACTION 开始一个事务

  COMMIT TRANSACTION 提交一个事务

  ROLLBACK TRANSACTION 回滚一个事务

  事务可以嵌套,可以通过全局变量@@trancount检索到连接的事务处理嵌套层次。要特别注意的是,每个显示或隐含的事物开始都使得该变量加1,每个事务的提交使该变量减1,每个事务的回滚都会使得该变量置0,而只有当该变量为0时的事务提交(最后一个提交语句时),才把物理数据写入磁盘。

  数据类型的选择 

  数据类型的合理选择对于数据库的性能和操作具有很大的影响,有关这方面的书籍也有不少的阐述,笔者这里主要介绍几点经验:

  1. Identify字段不要作为表的主键与其它表关联,这将会影响到该表的数据迁移。

  2. Text 和Image字段属指针型数据,主要用来存放二进制大型对象(BLOB)。这类数据的操作相比其它数据类型较慢,因此要避开使用。

  3. 日期型字段的优点是有众多的日期函数支持,因此,在日期的大小比较、加减操作上非常简单。但是,在按照日期作为条件的查询操作也要用函数,相比其它数据类型速度上就慢许多,因为用函数作为查询的条件时,服务器无法用先进的性能策略来优化查询而只能进行表扫描遍历每行。

时间: 2024-08-01 20:57:14

数据库设计优化经验谈的相关文章

高并发,大容量,高性能数据库设计优化

1.数据存储 a.集中式---->分布式 复制m/s.切分 a.1切分 垂直切分(按功能模块) 难点:跨域的表关联--->应用程序 事务---------->分布式的事务(单独数据源的小事务,然后通过程序控制) 某些表访问剧增----->读写分离 读写分离(异构数据源之间的读写分离) 相同数据源,只需要master/slave 难点:异构数据源之间的全量复制问题 异构数据源之间的增量同步问题(解析日志) 水平切分(按记录切分---->找规则) a.2 数据切分及整合的中间件

数据库设计优化

物理设计: 物理设计要做什么? 选择合适的数据库管理系统. 考虑因素:成本,业务场景,开发语言,功能,操作系统等. 数据库类型 成本 开发语言 支持系统 业务场景 Oracle 商业型 php,java,python等 windows/liunx系统 企业级 SQLServer 商业型 .NET,C#等 只支持windows系统 企业级 MySQL 开源型 php,java,python等 windows/liunx系统 中小型 PgSQL 开源型 php,java,python等 window

<<MySchool数据库设计优化>> 内部测试

1) 在SQL Server 中,为数据库表建立索引能够( C ). A. 防止非法的删除操作 B. 防止非法的插入操作 C. 提高查询性能 D. 节约数据库的磁盘空间 解析:索引的作用是通过使用索引,大大提高数据库的检索速度,改善数据库性能 2) 在SQL SERVER中,创建一个表使用(  C)语句. A. INSERT B. DROP C. CREATE D. ALERT 解析:A :insert 插入数据.   B: drop 进行删除操作 D:alter 添加约束 3) 在SQL SE

SQL Server 数据库性能优化(转载)

原文地址:http://www.cnblogs.com/sydeveloper/archive/2013/04/03/2992881.html 一.数据库设计优化 1.不要使用游标. 使用游标不仅占用内存,而且还用不可思议的方式锁定表,它们可以使DBA所能做的一切性能优化等于没做.游标里每执行一次fetch就等于执行一次select. 2.创建适当的索引 每当为一个表添加一个索引,select会更快,可insert和delete却大大变慢,因为创建了维护索引需要许多额外的工作. (1)采用函数处

SQL Server 数据库性能优化

1. 查看执行时间和cpu set statistics time on select * from Bus_DevHistoryData set statistics time off 执行后在消息里可以看到 2. 查看查询对I/O的操作情况 set statistics io on select * from Bus_DevHistoryData set statistics io off 执行之后的结果: 扫描计数:索引和表执行次数 逻辑读取:数据缓存中读取的页数 物理读取:从磁盘中读取的

[转] SQL Server 数据库性能优化

分析比较执行时间计划读取情况 1. 查看执行时间和cpu set statistics time on select * from Bus_DevHistoryData set statistics time off 执行后在消息里可以看到 2. 查看查询对I/O的操作情况 set statistics io on select * from Bus_DevHistoryData set statistics io off 执行之后的结果: 扫描计数:索引和表执行次数 逻辑读取:数据缓存中读取的

数据库如何优化

一.数据库设计优化 1.不要使用游标. 使用游标不仅占用内存,而且还用不可思议的方式锁定表,它们可以使DBA所能做的一切性能优化等于没做.游标里每执行一次fetch就等于执行一次select. 2.创建适当的索引 每当为一个表添加一个索引,select会更快,可insert和delete却大大变慢,因为创建了维护索引需要许多额外的工作. (1)采用函数处理的字段不能利用索引 (2)条件内包括了多个本表的字段运算时不能进行索引 3.使用事务 对于一些耗时的操作,使用事务可以达到很好的优化效果. 4

架构设计:系统存储(8)——MySQL数据库性能优化(4)

================================ (接上文<架构设计:系统存储(7)--MySQL数据库性能优化(3)>) 4-3.InnoDB中的锁 虽然锁机制是InnoDB引擎中为了保证事务性而自然存在的,在索引.表结构.配置参数一定的前提下,InnoDB引擎加锁过程是一样的,所以理论上来说也就不存在"锁机制能够提升性能"这样的说法.但如果技术人员不理解InnoDB中的锁机制或者混乱.错误的索引定义和同样混乱的SQL写操作语句共同作用,那么导致死锁出现的

架构设计:系统存储(9)——MySQL数据库性能优化(5)

=================================== (接上文<架构设计:系统存储(9)--MySQL数据库性能优化(5)>) 4-3-3-3.避免死锁的建议 上一篇文章我们主要介绍了MySQL数据库中锁的基本原理.工作过程和产生死锁的原因.通过上一篇文章的介绍,可以确定我们需要业务系统中尽可能避免死锁的出现.这里为各位读者介绍一些在InnoDB引擎使用过程中减少死锁的建议. 正确使用读操作语句 经过之前文章介绍,我们知道一般的快照读是不会给数据表任何锁的.那么这些快照读操作