数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

oracle中怎么确定性能差的SQL语句


发布日期:2019年10月31日
 
oracle中怎么确定性能差的SQL语句

前者很容易定位所有的操作系统都可以让我们查看 CPU 密集型任务这些任务可以追溯到一个特定用户一个特定应用程序模块 CPU 密集型模块一般都是由较差的代码和/或结构造成而不是性能差的 SQL一旦确定模块你必须试图使之更有效率一个可能的解决方案是将把某些处理移除程序让数据库处理(高明点的 SQL存储对象内联函数数组处理等)

第二个是 I/O 密集型的 SQL 语句这些语句会导致大量的数据库 I/O(全表扫描排序更新等)并以很高代价运行几个小时从 Oracle 开始解决了 SQL 识别问题通过查询数据库共享池区域我们可以很容易确定大多数 I/O 密集型 SQL 语句

下面 SQL 语句演示了如何确定 I/O 命中率低于 %的 SQL 语句这个命中率是自从 SQL 语句第一次被解析到共享池通过所有执行的语句反应整体 I/O下面可能是最近几分钟或几天的结果

代码如下
sql> SELECT executions

disk_reads

buffer_gets

ROUND((buffer_gets disk_reads) / buffer_gets ) hit_ratio

sql_text

FROM v$sqlarea

WHERE executions >

AND buffer_gets >

AND (buffer_gets disk_reads) / buffer_gets <

order by desc ;

EXECUTIONS DISK_READS BUFFER_GETS HIT_RATIO SQL_TEXT

SELECT SKUPREPACK_INDCASE_IDTRANSFER_QTYUNIT_COSTUNIT_RETAILROWID

FROM TSF_DETAIL WHERE transfer = : order by sku

SELECT TRANSFERTO_STORETO_WH FROM TSFHEAD WHERE TRANSFER = :b AND

TRANSFER_STATUS = A

SELECT SKU FROM UPC_EAN WHERE UPC = :b

SELECT SUBSTR(DESC_UP)DEPTSYSTEM_IND FROM DESC_LOOK WHERE

SKU = :b

SELECT UNIT_COSTUNIT_RETAILSUBCLASS FROM WIN_SKUS WHERE SKU = :b

事实上我们发现对特定的 SQL上面的数据有些误导其实语句没有问题考虑下面 v$sqlarea 输出

Executions Disk_Reads Buffer_Gets Hit_Ratio Sql_Text

SELECT AEMP_NO

该语句的命中率很低但事实上它很有效因为SQL 是通过 UNIQUE 索引操作的物理磁盘读取的数量几乎与逻辑读取一样UNIQUE 索引显着减少了整体的物理和逻辑磁盘 I/O 数量导致了一个令人误解的低命中率

下面例子命中率很好但是真的很好吗?

代码如下
Executions Disk_Reads Buffer_Gets Hit_Ratio Sql_Text

SELECT AEMP_NO

这个 SQL 语句看上去很有效但是 当我们仔细看时事情就不是那么回事了命中率并没有透露出该语句存在五个表连接并且每次执行进行了超过 个物理磁盘读取这是否太多了?是否有效?若不进一步研究无法回答这两个问题事实上这个实例中五个表的中其一个错误地执行了全表扫描通过重新构造 SQL我们可以减少物理磁盘 I/O 到小于 同时也显着减少逻辑磁盘 I/O巧合的是命中率也下降到不到

我们首选 V$SQLAREA 查询是每个语句执行的物理磁盘 I/O 的真实报告命中率是信息性的但有时会产生误导逻辑 I/O 相关的很少如果语句执行 个逻辑 I/O但只用了不到十分之一秒这就没人在乎了这是总的物理 I/O几乎消耗了所有的时间和确定潜在不正确的 SQL例如

代码如下
sql> SELECT sql_text executions

ROUND(disk_reads / executions ) reads_per_run

disk_reads buffer_gets

ROUND((buffer_gets disk_reads)

/ buffer_gets ) hit_ratio

sql_text

FROM v$sqlarea

WHERE executions >

AND buffer_gets >

AND (buffer_gets disk_reads) / buffer_gets <

ORDER by desc ;

前两个语句会报告更具启发性的结果

代码如下
Executions Reads_Per_Run Disk_Reads Buffer_Gets Hit_Ratio Sql_Text

SELECT

SELECT

从视图 V$SQLAREA 中我们可以立即隔离所有具有高物理读取的语句这些语句可能并不一定低效或写得不好但恰恰是它们需要进一步调查或调整

上一篇:oracle数据库sql的优化总结

下一篇:如何对Oracle中的优化器进行评估优化