執行個體優化ORACLE資料庫效能

小云云
發布: 2017-12-11 13:10:22
原創
1584 人瀏覽過

本文主要介紹了從實例著手分析ORACLE資料庫效能最佳化問題以及解決方法,需要的朋友參考下吧,希望對大家有幫助。 ORACLE資料庫的最佳化方式和MYSQL等很大的區別,今天透過一個ORACLE資料庫實例從表格、資料等各個方便分析如何進行ORACLE資料庫的最佳化。

tsfree.sql視圖

這個sql語句迅速的對每一個表空間中的空間總量與每個表空間中可用的空間的總量進行比較

表空間是資料庫的邏輯劃分,一個表空間只能屬於一個資料庫。所有的資料庫物件都存放在指定的表空間中。但主要存放的是表, 所以稱作表空間。

SELECT FS.TABLESPACE_NAME "Talbspace",
(DF.TOTALSPACE - FS.FREESPACE) "Userd MB",
FS.FREESPACE "Free MB",
DF.TOTALSPACE "Total MB",
ROUND(100 * (FS.FREESPACE / DF.TOTALSPACE)) "Pct Free" FROM
(SELECT TABLESPACE_NAME, ROUND(SUM(BYTES) / 1048576) TOTALSPACE FROM
DBA_DATA_FILES GROUP BY TABLESPACE_NAME) DF,
(SELECT TABLESPACE_NAME, ROUND(SUM(BYTES) / 1048576) FREESPACE
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME) FS WHERE DF.TABLESPACE_NAME = FS.TABLESPACE_NAME;
登入後複製

varray 表的使用

#
CREATE OR REPLACE TYPE EMPLOYER_NAME AS OBJECT (E_NAME VARCHAR(40));

CREATE OR REPLACE TYPE PRIOR_EMPLOYER_NAME_ARR AS VARRAY(10) OF 
EMPLOYER_NAME;

CREATE OR REPLACE TYPE FULL_MAILLING_ADRESS_TYPE AS OBJECT(STREET 
VARCHAR2(80), CITY VARCHAR2(80), STATE CHAR(2), ZIP VARCHAR2(10));

CREATE OR REPLACE TYPE EMPLOYEE AS OBJECT(LAST_NAME VARCHAR(40), 
FULL_ADDRESS FULL_MAILLING_ADRESS_TYPE, PRIOR_EMPLOYERS 
PRIOR_EMPLOYER_NAME_ARR);

CREATE TABLE EMP OF EMPLOYEE;

INSERT INTO EMP VALUES('Jim', FULL_MAILLING_ADRESS_TYPE('Airplan Ave', 'Rocky', 'NC', '2343'), PRIOR_EMPLOYER_NAME_ARR(EMPLOYER_NAME('IBM'), EMPLOYER_NAME('APPLE'), EMPLOYER_NAME('CNN')));
登入後複製

-- 回滾

DROP TYPE PRIOR_EMPLOYER_NAME_ARR FORCE;
DROP TYPE FULL_MAILLING_ADRESS_TYPE FORCE;
DROP TYPE EMPLOYEE FORCE;
DROP TYPE EMPLOYER_NAME FORCE;#PDR FORCE;
DROP TYPE EMPLOYER_NAME NAME. P.LAST_NAME, PRIOR_EMPLOYERS.*
FROM EMP P, TABLE(P.PRIOR_EMPLOYERS) PRIOR_EMPLOYERS
WHERE P.LAST_NAME = 'Jim';

SQL問題檢查安全性,確保sql資料執行者有權限執行

2,檢查sql語法

3,可能發生的查詢重新書寫

4,執行


##

创建执行计划
生产器接受经过解析的sql
捆绑执行计划 执行执行计划 读取结果记录 排序结果集
登入後複製


資料存取方式:

1,全表扫描 db_file_multiblock_read_count = 128
一次性最大读取block的数量
Oracle开启并行: Alter table employee parallel degree 35;
 顺序读取,直到结尾
1,当表中不存在索引
2,查询中不包含where字句
3,内置函数中的索引无效
4,like操作 %开头
5,使用基于成本优化器 数据量少时
6,当初始化文件中存在optimizer_mode = all_rows
7,负向条件查询不能使用索引 例如 status != 0, not in, not exists 可以优化为 in (2,3);
登入後複製

下列情況的SQL語句會導致全表掃:

1,使用null条件查询导致全表扫,因为索引不能为空
为了绕过全表扫这个问题,可以采取这样的方法 
update emp set name = 'N/A' where name is null; 
select name from emp where name = 'N/A';
2,对没有索引的字段查询,找到where条件后面的查询不带索引的字段,加索引可以
大大提高查询性能。
3,带有like条件的查询 like '%x%' 全表扫描,like 'x%' 不会全表扫,因为like
以字符开始。
4,内置的函数使索引无效,对于Date类型的数据来说非常的严重
内置函数 (to_date,to_char)
如果没有创建与内置函数匹配的基于函数的索引,那么这些函数通常会导致sql优化器全表扫描
select name from emp where date < sysdate -8;
检查where子句脚本是否含有 substr to_char decode
SELECT SQL_TEXT, DISK_READS, EXECUTIONS, PARSE_CALLS
FROM V$SQLAREA
WHERE LOWER(SQL_TEXT) LIKE &#39;%substr%&#39;
OR LOWER(SQL_TEXT) LIKE &#39;%to_char%&#39;
OR LOWER(SQL_TEXT) LIKE &#39;%decode%&#39;
ORDER BY DISK_READS DESC;
使用函数索引解决这个问题

5,all_rows 优化器目标是提高吞吐量而且倾向于使用全表扫描,因此 对于任何一
个要求sql快速查询返回部分结果集而言,optimizer_mode 
应该设置为first_rows

6,经验上,能过滤80%数据时就可以使用索引,对于订单状态,如果状态很少,不宜
使用索引,如果状态值很多可以使用索引。

7,如果查询字段大部分是单条数据查询,使用Hash索引性能更好
原因:B-TREE 索引的时间复杂度是O(log(n))
Hash 索引的时间复杂度是O(1)
   
8,符合索引最左前缀,例如建立符合索引(passWord,userName)
select * from user u where u.pass_word = ? and u.user_name = ? 可以命中索引
select * from user u where u.user_name = ? and u.pass_word= ? 可以命中索引
select * from user u where u.pass_word = ? 可以命中索引
select * from user u where u.user_name = ? 不可以命中索引
登入後複製

如何找出影響力高的sql語句

 视图 v$sqlarea ,下列参数按照重要性从高到低排序
 executions :越经常执行的sql语句就应当越早的调整,因为它会对整体的性能产生巨大的影响。
 disk_reads: 磁盘读取,高的磁盘读取量可能表明查询导致过多的输入输出量。
 rows_processed:记录处理,处理大量的记录的查询会导致较大的输入输出量,同时在排序的时候对TEMP表空间产生影响。
 buffer_gets:缓冲区读取,高的缓冲读取量可能表明了一个高资源使用量的查询。
 sorts:排序会导致速度的明显减低,尤其是在TEMP表空间中进行的排序。
登入後複製

2.賽列取得

#

Oracle对单表簇和多表簇进行散列存储,用来在连接操作中减低输入 输出
登入後複製

3,ROWID 存取

透過Rowid存取單一資料最快的方式,在實際的引用中,首先從索引收集ROWID,然後透過ROWID進行資料讀取

索引存取方式

索引都可以看做一组符合主键和ROWID的组合,索引访问的目的是收集对目标快速读取时所需要的ROWID
登入後複製

#B樹索引,點陣圖索引基於函數的索引.

索引範圍掃描:讀取一個或多個ROWID 索引數值升序排列

eg:select * from table where a = &#39;a&#39;;
登入後複製

快速全索引掃描

eg: select distinct color,count(*) from table group by color;

單一索引掃描:讀取一個單獨的ROWID

降序索引範圍掃描:讀取一個或多個ROWID索引數值降序排列


AND - EQUALS: select * from table where a = 'a' and b > 34; 從where字句收集多個ROWID


#連接操作


嵌套循環連接


雜湊連接


散列連接通常快於嵌套循環連接,特別是在驅動表以及在查詢的where子句中過濾,只剩下少量的記錄的情況下


排序合併連接


連接提示:


表反向连接提示,例如,NOT IN, NOT EXISTS
尽量避免使用 NOT IN 子句(它将调用子查询),而应该使用NOT EXISTS 子句(它将调用相关联的子查询),
因为如果子查询返回的任何一条记录中包含空值,那么该查询将不会返回记录,如果允许NOT IN 子句查询为空,那么
这种查询的性能非常的低,子查询会在外层查询块中对每一条记录重新执行一次。
登入後複製

排序大小sort_area_size_init.ora 參數,在控制台查看sort_area_size;

查詢語句:show parameter sort_area_size;


磁碟排序的執行速度要比記憶體排序的的執行速度慢14000倍


磁碟排序之所以昂貴,有以下幾個原因:


1,同在記憶體中進行排序比較,速度太慢

2,磁碟排序耗費臨時表空間的資源


資料庫分配2個臨時表空間:



# select DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE from dba_users where username='SYS';


select * from dba_temp_free_space;


Oracle臨時表空間主要充當兩個主要作用:臨時資料表段分配和排序匯總溢位段。


排序匯總溢位的範圍比較廣泛。我們在SQL語句中進行order by/group by等操作,


首先是選擇PGA的記憶體sort area、hash area和bitmap area。


如果SQL使用排序空間很高,單一server process對應的PGA不足以支撐排序要求的時候,臨時表空間會充當排序段的資料寫入。

而磁碟排序會降低單一任務的速度,同時也會影響Oracle實例中正在執行的其他任務,而且過多的磁碟排序將導致過多的空閒緩衝等待

#以及將其他任務的資料區塊從緩衝池中分頁出去的昂貴代價。

Oracle首先嘗試在sort_area_size 分配的記憶體區中進行排序,Oracle只有不能再記憶體中排序時,才會呼叫磁碟排序
並將記憶體框架遷移到TEMP表空間,繼續進行排序。

使用索引範圍掃描的總體原則


 -- 对于原始排序的表, 仅读取少于40%的表记录查询就应该使用索引范围扫描,反之,多余40%,使用全表扫。
 -- 对于未排序的表, 仅读取少于7%的表记录查询就应该使用索引范围扫描,反之,多余7%,使用全表扫。
登入後複製

#表的存取方式

sql優化器

對於任何一個sql語句來說,存在著唯一的最佳化表存取方式,而你的工作就是找到這種方式,並且長期使用它。


db_file_multiblock_read_count


目的是為sql語句產生最快且好資源最少的執行計劃


1,基於規則的最佳化器


步骤 
对于在where子句中的每一个表
-- 生成一个可行的执行计划列表,这个列表中列出所有可以用来访问表的路径
-- 为每一个执行计划指定级别数值
-- 选择级别数值最低的计划
-- 对结果集的选择级别最低 连接方法进行评估
 
基于规则优化器(PBO)特征
- 总是使用索引,使用索引永远比使用全表扫描或使用排序合并连接(排序合并连接不需要索引)更加可取
- 总是从驱动表开始 在from字句的最后一个表是驱动表,在这个表中选择的记录数应该是最少(查询返回值最少),RBO在执行嵌套循环连接
操作时,将这个驱动表作为第一个操作表。
- 只有在不可避免的情况下才使用全表扫描
-任何索引都可以
- 有时越简单越好
登入後複製

2,基於成本的最佳化器(CBO)

 基于规则优化提供更加复杂的优化替代方案
 ANALYZE TABLE TT_TCAS_HK_QTY COMPUTE STATISTICS;
 ANALYZE TABLE TT_TCAS_HK_QTY ESTIMATE STATISTICS SAMPLE 5000 ROWS;
 ANALYZE TABLE TT_TCAS_HK_QTY ESTIMATE STATISTICS SAMPLE 5000 ROWS FOR ALL INDEXED COLUMNS;
 
 CBO在以下情况会选择错误的全表扫描
 1,最高峰值过高
 2,错误的optimizer_mode,如果optimizer_mode设置为all_rows,choose,那么sql优化器会倾向于使用全表扫描。
 3,多表连接,存在多余3张表连接时,即使连接中存在索引,cbo仍然会对这些表进行全表扫描。
 4,不平衡的索引分布,比如 color = &#39;blue&#39; color字段上有索引,但是只有1%的记录属于blue,
登入後複製

SQL 的SGA統計資料

select name,value from v$sysstat where name like 'table%'

table scans(short table) -- 對小表全表掃描的次數

table scans(long table) -- 對大表全表掃描的次數,評估是否通過加索引減少大表的掃描次數或透過呼叫Oracle並行(opq)來提高查詢的執行速度。

table scans Rows Gotten -- 這個數字說明全表掃描掃描記錄條數

table scans blocks Gotten -- 掃描取得資料庫的數目

Table fetch by rowid -- 透過索引存取記錄的數目,這裡的索引通常是巢狀循環連接

table fetch by Continued Row -- 這個數字說明與其他資料區塊連接在一起的記錄數目

程式庫快取中可以多次使用的SQL

Oracle在辨識"相同的"sql語句是存在問題

例如:select from customer; Select From Customer; 儘管區別字母的大小寫,Oracle會對第二個sql語句進行重新編譯執行;

相關推薦:

詳解oracle分頁查詢的基礎原則

MySQL 與 Oracle之間的「較量」

關於oracle擴充使用的方法總結

以上是執行個體優化ORACLE資料庫效能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!