数据库最主要的就是数据库设计冗余,还是sql语句之类的,还有就是用存储过程比一般的sql语句快等到;其次就是编程代码的问题,例如if
else
if
else
if
else这个判断的,如果用switch的话就会快很多
Ⅱ GBase8s数据库SQL语句性能缓慢从哪个方面入手分析
在实际的生产运行环境中,很多客户现场都看到开发人员和系统管理人员遇到很多有关于GBase 8s 数据库引起的性能问题,进而被多次问起如何进行GBase 8s 数据库性能调优,
性能优化原则
包括:
性能规划:深入了解应用与数据库的交互特征,确立良好的设计、开发、测试迭代过程,上线前消除模型上的性能瓶颈。
实例调优:建立性能基准,对比调节数据库、操作系统、存储、网络等的配置,主动监控、消除瓶颈。
SQL 调优:书写高效 SQL,优化相关数据库对象,充分借助优化器,确定最佳执行计划。
性能优化流程
首先执行下面的初始检查:
– 获取直接用户的使用反馈,确定性能目标和范围。
– 获取性能表现好与坏时的操作系统、数据库、应用统计信息。
– 对数据库做一次全面健康检查。
根据收集的信息,以及对应用特性的了解,构建性能概念模型,明确性能瓶颈所在,以及导致性能的根本原因。
– 首先应该排除操作系统、硬件资源造成的瓶颈。
– 然后针对数据库系统性能进行分析
– 必要时,还需要检查应用日志,因为系统性能问题也可能由于应用非 SQL 部分造成瓶颈。
提出一系列针对的优化措施,并根据它们对性能改善的重要程度排序,然后逐一加以实施。不要一次执行所有的优化措施,必须逐条尝试,逐步对比。
通过获取直接用户的反馈验证调节是否已经产生预期的效果,否则,需要重新提炼性能概念模型,直到对应用特性了解进一步准确。
重复上述,直到性能达到目标或由于客观约束无法进一步优化。
常见调优技巧
找到 CPU 占用最高的 SQL
在 sysmaster 库中执行
select sqx_estcost, sqx_sqlstatement
from syssqexplain
order by sqx_estcost desc
1
2
3
注意:此时看到的仅仅是当前正在执行的 SQL
需要多看几次
onstat 命令
onstat -g act 得到当前正在执行的 SQL
根据 rstcb 列
onstat -u | grep 57c68220
1
从第三列 sessid 得到 SESSION
onstat -g ses SESSION 即可得到当时正在执行的 SQL
一般多找几个 threads 后,就基本可以确定问题 SQL
得到 SQL 后,利用 set explain on 分析其查询路径,看是否未利用索引,在对大表进行全表扫描,根据需要创建相应索引。
找到全表扫描较多的表及其 SQL
得到全表扫描较多的表
-- 系统顺序扫描较多时,被多次顺序扫描的大表,如果有,应该考虑增加索引
select first 5
substr(t.tabname,0,20) tabname,
substr(dbsname,0,10) dbname,
nrows*rowsize*p.seqscans costs,
substr(p.seqscans,0,8) seqscans,
substr(nrows,0,8) nrows
from sysmaster:sysptprof p , systables t,sysmaster:sysprofile s
where p.tabname = t.tabname
and p.seqscans > s.value/50
and s.name = 'seqscans'
--and s.value > 2000000 and nrows > 2000
order by 3 desc
1
2
3
4
5
6
7
8
9
10
11
12
13
利用 onstat –g ses 0 –r 5/ onstat –g stm 的输出信息,根据表名,找到可能的 SQL 语句。由于以上获取 SQL 的办法是有局限的,如果无法获取,建议通过查看应用日志或联系开发人员查看源代码的方式来找到。
利用 set explain on 分析其查询路径,确认是在对表进行全表扫描,根据需要创建相应索引。
Ⅲ 如何解决SQL查询速度太慢
1. 执行计划中明明有使用到索引,为什么执行还是这么慢?
2. 执行计划中显示扫描行数为 644,为什么 slow log 中显示 100 多万行?
a. 我们先看执行计划,选择的索引 “INDX_BIOM_ELOCK_TASK3(TASK_ID)”。结合 sql 来看,因为有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能会更差,优化器选择这个索引避免了排序。
那为什么不选 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很简单,TASK_DATE 字段区分度太低了,走这个索引需要扫描的行数很大,而且还要进行额外的排序,优化器综合判断代价更大,所以就不选这个索引了。不过如果我们强制选择这个索引(用 force index 语法),会看到 SQL 执行速度更快少于 10s,那是因为优化器基于代价的原则并不等价于执行速度的快慢;
b. 再看执行计划中的 type:index,"index" 代表 “全索引扫描”,其实和全表扫描差不多,只是扫描的时候是按照索引次序进行而不是行,主要优点就是避免了排序,但是开销仍然非常大。
Extra:Using where 也意味着扫描完索引后还需要回表进行筛选。一般来说,得保证 type 至少达到 range 级别,最好能达到 ref。
在第 2 点中提到的“慢日志记录Rows_examined: 1161559,看起来是全表扫描”,这里更正为“全索引扫描”,扫描行数确实等于表的行数;
c. 关于执行计划中:“rows:644”,其实这个只是估算值,并不准确,我们分析慢 SQL 时判断准确的扫描行数应该以 slow log 中的 Rows_examined 为准。
4. 优化建议:添加组合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)
优化过程:
TASK_DATE 字段存在索引,但是选择度很低,优化器不会走这个索引,建议后续可以删除这个索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+
在这个 sql 中 REL_DEVID 字段从命名上看选择度较高,通过下面 sql 来检验确实如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+
由于有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 组合选择度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+
在测试环境添加 REL_DEVID,TASK_ID 组合索引,测试 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引后执行计划:
这里还要注意一点“隐式转换”:REL_DEVID 字段数据类型为 varchar,需要在 sql 中加引号:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'
执行时间从 10s+ 降到 毫秒级别:
1 row in set (0.00 sec)
结论
一个典型的 order by 查询的优化,添加更合适的索引可以避免性能问题:执行计划使用索引并不意味着就能执行快。
Ⅳ oracle数据库运行sql很卡很慢很顿,看等待事件都是cursor:pin s on x,这是啥
详解cursor: pin S wait on X等待事件
‘cursor: pin * events’等待事件
该类等待事件一般是为了pin相关的子游标
‘Cursor: pin S on X’ 最常见的等待事件, 进程为了共享操作例如执行pin游标而以SHRD S mode申请mutex, 但是未立即获得。原因是该游标被其他进程以EXCL X mode 持有了。
实际该 cursor: pin S wait on X等待事件往往是由于其他因素诱发的。Mutex争用仅仅是问题的症状,但根本原因需要Database Consultant 进一步挖掘。
下面我们列出一些已知的常见案例, 在这些例子中可以看到 我上面提到的 Mutex的争用仅仅是伪争用:
过多的子游标 High Version Counts
过多的子游标版本Version Count可能导致Mutex 争用,一般一个SQL的Version Count不要高于500。
检查High Version Count很简单, 在AWR里就有SQL ordered by High Version Count,也可以写SQL查V$SQL、V$SQLAREA
昂贵的X$、V$视图查询
一些对于V$、X$视图的查询,需要访问X$KGL*之类的fixed table,可能触发Mutex争用。
Mutex持有者得不到CPU
Mutex持有者若得不到足够的CPU片可能一直阻塞他人,直到它拿到需要的CPU。
这种情况可能由于OS操作系统的实际情况或者使用Resource Manager而引起。需要配合AWR中的Host CPU、Instance CPu一起看。
已经被KILLED的SESSION仍持有Mutex
当session正持有Mutex,而其对应的Process被强制KILL掉, 则直到PMON彻底清理掉该Dead Process并释放Mutex,其他session才能不再等待。 诊断该类问题,最好能检查PMON的TRACE。 当然也存在部分BUG会导致PMON清理过程非常慢。
举例来说,bug 9312879描述了一种场景:PMON 需要获得某个Mutex以便清理某个dead process,但是该Mutex又被其他进程持有,则PMON甚至无法开始真正清理并释放Mutex。
如果自己搞不定可以找ASKMACLEAN专业ORACLE优化团队成员帮您搞定!
Ⅳ 数据库写入数据很卡,查询也很慢,懂的高手请来,赏分解决可以追加分
看这种现象,估计是SQL语句写的不够好,SQL要用绑定变量的方式,影响查询性能主要就是执行SQL过多,而且SQL写的不好,无效索引过多,第一步必须优化SQL,之后就是清理历史数据,清理无用索引,大表数据可以用分区表,还有就是tomcat的性能也需要注意,如果太卡,重启一下tomcat试试,是否有效果
Ⅵ sql数据库写入时慢做其他的很正常
数据量多大了?看看有没有一些不应该做索引的字段做了索引,如果写了触发器看看触发器的运行是否有问题。最好直接用SQL查询分析器运行下插入,看看问题所在。
Ⅶ oracle数据库执行sql很慢怎么回事
由于经常执行sql语句,如果一条一条执行效率低下。
oarclecmd.commandtext
=
sqlstr;
oraclecmd.executenonquery();
sqlstr
可以写成如下所示语句
begin
sql1;
sql2;
......
sqln;
end;
//注意此处的分号很重要
然后同样调用executenonquery()方法,可以一次执行多条sql语句。