SQL语言艺术30则

1.       表中有些字段出现了空值,表明需要引入子类型。

2.       性能拙劣的罪魁祸首,是错误的设计。

3.       在合理范围内,利用每次数据库访问完成尽量多的工作

4.       只要有可能,应尽量把条件逻辑放到SQL语句中,而不是SQL的宿主语言中。

注:按自己的理解,就是可以使用SQL解决的问题,尽量不要使用PL/SQL;可以使用PL/SQL解决的问题,尽量不要使用cJava

5.       建立索引项需要记录物理地址,于是就要求将记录插入表,后将索引项插入索引。如果违反了唯一性约束,数据库会取消不完全的插入,并返回违反约束的错误信息。

6.       在事务处理型数据库中,“太多索引”往往意味着设计不够稳定。

7.       记录的排列顺序与索引键相同,可以提高范围(range)查询的速度。

8.       查询条件的字段上加函数f(),会使索引无法发挥作用。原因是,无法保证函数f()值的顺序与索引数据的相同。

函数索引的使用通常暗示设计存在问题,数据模型甚至连基本的数据原子性问题都没有解决。

9.       Oracle允许建立逆序索引(reverse index),保存索引之前先将组成键的bit序列(sequence of bits)进行逆向排列。逆序索引对范围搜索无效。

注:(1)逆序索引的主要目的是为了降低在并行服务器环境下索引叶块的争用。

(2)为何逆序索引对范围搜索无效其实很好理解,逆序也可以看做是函数的一种,只不过这次函数是用在了索引上。

10.     我们可以将SQL查询表示为一个两层的操作。第一层是一个关系操作的“核”,它负责找出我们要操作的数据集;第二层是“非关系操作层(non-relaional layer)”,它对有限的数据结果集进行“精雕细刻”从而产生用户期望的最终结果。最稳妥的办法就是在关系操作层完成尽量多的工作,因为关系操作层的执行可以优化。对于不完全是关系操作的SQL部分,应加倍留意查询的编写。

11.     在编写查询之前,我们甚至应该对过滤条件进行排序,真正高效的条件(可能有多个,涉及到不同的表)是查询的主要驱动力,低效条件只起到辅助作用。首先,要看过滤条件能否尽快减少必须处理的数据量。

12.     试图优化数据的物理布局常碰到两个冲突的目标。一个目标是,尽量以紧凑的方式存储数据,这有利于查询尽快找到所有数据。另一个目标则是,尽量将数据分散存储,以便多个进程可以并发写入,不会造成资源争用而互相妨碍。

读和写不会和睦相处:读操作希望数据聚集在一起,而并发的写入操作希望数据是分散保存的。

13.     分区是把双刃剑。一方面,它通过分区键将数据聚集在一起,利于高速检索。另一方面,对并发执行的插入操作,分散数据可避免出现“访问过于集中”的问题。

对分区表进行查询,当数据按分区键均匀分布时,收益最大。

14.     我们有理由假定,除了默认存储方式之外的任何存储方式,无论看起来有多好用,都会带来一定程度的复杂性,且该复杂性远远超出了采用这种存储方式带来的好处(也可能没有任何好处)

15.     类似的索引,性能却不同,这可能是物理数据的散布引起的。

16.     如果要使用子查询,在选择关联子查询,还是非关联子查询的问题上,应仔细考虑。

处理大量记录时,关联子查询(Correlated subquery)是性能杀手。当一个查询包含多个子查询时,必须让它们操作各不相同、自给自足的数据子集,以免子查询互相依赖;到查询执行的最后阶段,多个子查询分别得到的不同数据集经过哈希连接或集合操作得到结果集。

17.     OLAP函数属于SQL的非关系层。这类函数的作用是:在查询中做最后(或几乎是最后)处理。因为他们在过滤已完成后对结果集进行处理。

18.     当存在关联子查询时,就必须执行外层查询,接着对所有通过过滤条件的记录,执行内层查询。外层查询和内层查询相互依赖,因为外层查询会把数据传递给内层查询。使用非关联子查询时情况要好得多,但也不是完全乐观:必须完成内层查询之后,外层查询才能介入。

19.     只要对象的类型相同、而对象的层数可变,其关系就应该被建模为树结构。在SQL的世界中,树通常可用三种模型描述。

(1) 邻接模型(Adjacency model)

(2)     物化路径模型(Materialized path model)

(3)     嵌套集合模型(Nested set model)

20.     遇到“前置码比较”或“基于键的一部分比较”等特殊情况时,可使用范围条件(range condition)来表达,并尽量使用下限值和上限值。

21.     SQL语句提交的速度比服务速度要快时,系统性能就会出现严重问题;所有查询都会受到影响,而不仅仅是慢速查询。

22.     我们在处理加锁问题时,要注意两个问题:

(1)     不要随便使用表级锁。

(2)     尽量缩短加锁时间。

23.     在事务内,应该:

(1)     尽可能避免SQL语句上的循环处理。

(2)     无论是以应用服务器或客户端执行,应尽量减少程序和数据库之间的交互次数,因为这增加了网络访问的开销。

(3)     充分利用DNMS提供的机制,使跨机器交互的次数降至最少。

(4)     把所有不重要的、不必须的SQL语句放在逻辑工作单元之外。

24.     并发完成任务的最佳session数量是和硬件相关的,再增加额外的session毫无作用。因此,去除多余的session,能减轻系统压力。

25.     通过调整分配给排序的内存数量来改善排序密集型操作(sort-heavy operation)的性能,是常见且有效的调优技巧。

26.     为了降低查询对数据量增加的敏感度,应该在较深层的查询中只操作绝对必要的数据,将辅助性的join操作留在外层。

27.     分布均匀性日期适合作为分区的原因、也是以日期进行范围分区广受欢迎的原因。

28.     Insert的代价相当高,因为插入新纪录时还必须维护“表上的索引”。而update只需要维护“更新字段上的索引”。但与insert相比,update的弱点是双重的:首先,update和搜索(where子句)密不可分,这可能与使用select一样引发灾难,加锁期间状况恶化。第二,先前的值(insert的情况下并不存在)必须保存在某个地方,已被回滚(rollback)Delete则涵盖了所有缺点,既会影响所有索引,又常与缓慢的where子句相伴相随,还必须保持删除值以备回滚时使用。

29.     判断查询性能的唯一标准,是花了多长时间执行,而不是执行计划是否符合偏见。

30.     设法使优化器采用完全不同的执行计划,可通过如下手段:
(1)
当返回少量记录时,应增加索引,或重建复合索引并调整其中字段的顺序;此时,将非关联子查询转换为关联子查询,也会有帮助。

(2)当返回大量记录时,做法相反,并在from子句中使用子查询,以建议表连接以不同顺序进行。

(3)如果没有把握,则还有很多其他选择。例如用unionwith子句分解查询。两个尽量使每个条件不依赖其他条件,通常也有帮助。一般来说,在干预优化器的执行顺序之前,应该首先尽量去除查询中强制的处理顺序,是优化器尽量自由。只有在别无选择的时候,才考虑干预优化器这一手段。

(4)最后一招,就是优化器指令,应小心使用。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21805468/viewspace-620243/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/21805468/viewspace-620243/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值