首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

数据库 SQL 语句性能调优 8 个技巧

由社区专家丁翼根据社区交流活动综合整理,来自多位社区会员分享。

一、DB2数据库常用的、需人工配置的参数有哪些?

DB2的参数比较多,分DB2SET参数、DB2 DBM CFG参数以及DB2 DB CFG参数等几个层面。

建库时,一般需要考虑的参数有各种上限类的参数或者指定某个内存池大小的参数(MAX开头的参数),比如MAXAPPLS,需要根据应用需要去设置,在系统资源允许的情况下,我们这边多数设置为AUTOMATIC。还有锁相关的参数(比如超时时间LOCKTIMEOUT、死锁探测周期DLCHKTIME等)需要结合应用程序的特性来设置。

在日常运维中,要基于发生的问题来调整参数。在发生问题时,需要进行深入分析,按照分析结果去修改参数。例如某数据库曾经发生过交易取sequence慢的问题,经过一系列分析发现跟page latch有关,最终调整了NUM_IOCLEANERS和NUM_IOSERVERS这两个参数,使问题得以优化。如果不分析具体问题,很难去凭空评判哪个参数应该怎样去调整。

二、除了DB2ADVIS,还有什么办法来根据SQL语句建立索引?

通过系统视图syscat.columns, syscat.coldist如何来查看字段分布和建立索引?为什么有些直接把column放在index里,有些放在include的条件里?

创建索引有些基本的原则,大体如下:

1、在适当地方定义主键和唯一索引。

2、创建关于查询用来连接表(Join)的任何列的索引。

3、创建关于基于常规基础从中搜索特定值的任何列的索引。

4、创建关于通常用在 ORDER BY 子句中的列的索引。

5、确保使用了仅检索您需要的数据的谓词。

6、当创建多列索引时,索引的第一列应该为查询中的谓词最常用的那一列。

7、确保索引造成的磁盘和更新维护的开销不会太高

在对表做runstats的时候 需要加上with distribution 选项,这样数据库就记录统计分布信息。

查看字段分布的语句如下:

select colname,colcard from syscat.columns where tabname='表名'

select colvalue,valcount,distcount from syscat.coldist where tabname='表名' and colname='字段名' and type='F'

创建索引是指定include的作用在于将非索引键存储在非聚集索引的叶级索引页面上,这样作的好处是不增加索引大小(level)的情况下,增大索引的覆盖范围。另外如果列过长,索引的效率也 是极低的,include能用到的场景不多。因为include列只能放在唯一索引的后面,所以,在查询语句当中选择的字段,除了出现在唯一索引中的以外,还有那么几个字段,就可以放在include里面 了,实现纯索引的扫描可以看出,这个要求是非常高的,所以只建议对查询量很大的语句进行这种优化。

三、如何抓取静态语句?

通过监控工具或快照找出相应的package name

然后

db2expln -d 数据库名 -c package模式名 -p package名 -g -i -o 输出文件名

在输出文件中 可以搜索section number 找到相应的sql语句和执行计划

四、在并发系统里,如何避免死锁?

对于死锁,问题的源头在于合理的应用程序设计,可以通过event monitor for locking或者查看db2diag.log找到发生死锁的应用,然后修改相应的code。修改程序逻辑,尽量避免ABC和BAC的情况。优化程序、SQL语句、索引等,减小单个事务拿锁的数量和时间。

五、reorg之后,为什么需要rebind?如何rebind?

reorg,runstats之后catalog table中存储的统计信息发生变更,对于dynamic SQL执行计划都是动态生成的,只用static SQL才需要rebind。因为static SQL的执行计划是在rebind时生成。只有静态语句需要rebind,也就是预先绑定的程序包。因为数据库对象发生了变化,db2优化器可能产生更优的查询计划,只有rebind才能用上最新的信息。

先找到涉及做过runstats的表的package名称,比如某个存储过程AAA的package这样找:

select lib_id from syscat.routines where routinename='AAA'

得出lib_id

select pkgschema,pkgname from syscat.packages where pkgname like '%刚才的lib_id值'

就能找出package模式名和名称

然后 db2 rebind package 模式名.名称

六、执行runstats收集统计信息操作会避开业务繁忙时段,但在无法避开表操作的时候,runstats有什么影响?

在db2中做查询的时候,以什么样的方式访问数据是由优化器来决定的。一般来说,优化器会采用最优的方式,选择最有效率的方式。选择的依据就是统计信息。所以统计信息不准了,优化器的决策自然也就有问题了。可能造成查询的缓慢,影响性能和效率。

runstats就是用来收集统计信息的。runstats可以基于频率或百分比进行数据分布采集。一般采取默认值即可。

一般还是建议在空闲时执行runstats。但如果有特殊情况,如窗口避不开,且表特别大,可以考虑抽样统计。或者使用允许写访问的选项在线收集,但在线收集表上会加in锁,如果期间表更改过多,也有可能导致收集的统计信息有偏差。

七、把DB2的监视开关都打开的话,会不会很消耗系统资源?

基于快照的那些开关对性能影响不大。在服务器资源没有瓶颈的情况下最好打开,在日常运维中,监视开关提供的快照数据很有用。

八、关于如何提高索引缓冲池命中率的问题?

索引缓冲池命中率低是不是只是从缓冲池这个维度去查看的结果?如果是这样的话不太准确,因为我们最终想看的是哪个表的哪个索引命中率低,这样才知道是不是有问题。这个可以从表空间的缓冲池命中率和相关sql的缓冲池命中率去确定。如果最终确定了是表的索引命中率低,有两个方向去调整。一个是增加buffer的大小。这种在buffer原先设置过小的情况下是很有效的。第二个是查还有谁占用了缓冲池,例如全表扫的大表,临时表等,把这些占buffer的东西都弄到其他表空间去占用单独的bufferpool。这样就能减少影响。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190118B04XCR00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券