SQL性能优化应该考虑哪些?
生活随笔
收集整理的這篇文章主要介紹了
SQL性能优化应该考虑哪些?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1
、調整數據結構的設計。這一部分在開發信息系統之前完成,程序員需要考慮是否使用
ORACLE
數據庫的分區功能,對于經常訪問的數據庫表是否需要建立索引等。
2 、調整應用程序結構設計。這一部分也是在開發信息系統之前完成,程序員在這一步需要考慮應用程序使用什么樣的體系結構,是使用傳統的 Client/Server 兩層體系結構,還是使用 Browser/Web/Database 的三層體系結構。不同的應用程序體系結構要求的數據庫資源是不同的。
3 、調整數據庫 SQL 語句。應用程序的執行最終將歸結為數據庫中的 SQL 語句執行,因此 SQL 語句的執行效率最終決定了 ORACLE 數據庫的性能。 ORACLE 公司推薦使用 ORACLE 語句優化器( Oracle Optimizer )和行鎖管理器( row-level manager )來調整優化 SQL 語句。
4 、調整服務器內存分配。內存分配是在信息系統運行過程中優化配置的,數據庫管理員可以根據數據庫運行狀況調整數據庫系統全局區( SGA 區)的數據緩沖區、日志緩沖區和共享池的大小;還可以調整程序全局區( PGA 區)的大小。需要注意的是, SGA 區不是越大越好, SGA 區過大會占用 操作系統使用的內存而引起虛擬內存的頁面交換,這樣反而會降低系統。
5 、調整硬盤 I/O ,這一步是在信息系統開發之前完成的。數據庫管理員可以將組成同一個表空間的數據文件放在不同的硬盤上,做到硬盤之間 I/O 負載均衡。
6 、調整操作系統參數,例如:運行在 UNIX 操作系統上的 ORACLE 數據庫,可以調整 UNIX 數據緩沖池的大小,每個進程所能使用的內存大小等參數。
實際上,上述數據庫優化措施之間是相互聯系的。 ORACLE 數據庫性能惡化表現基本上都是用戶響應時間比較長,需要用戶長時間的等待。但性能惡化的原因卻是多種多樣的,有時是多個因素共同造成了性能惡化的結果,這就需要數據庫管理員有比較全面的計算機知識,能夠敏感地察覺到影響數據庫性能的主要原因所在。另外,良好的數據庫管理工具對于優化數據庫性能也是很重要的。
ORACLE 數據庫性能優化工具
常用的數據庫性能優化工具有:
1 、 ORACLE 數據庫在線數據字典, ORACLE 在線數據字典能夠反映出 ORACLE 動態運行情況,對于調整數據庫性能是很有幫助的。
2 、操作系統工具,例如 UNIX 操作系統的 vmstat , iostat 等命令可以查看到系統系統級內存和硬盤 I/O 的使用情況,這些工具對于管理員弄清出系統瓶頸出現在什么地方有時候很有用。
3 、 SQL 語言跟蹤工具( SQL TRACE FACILITY ), SQL 語言跟蹤工具可以記錄 SQL 語句的執行情況,管理員可以使用虛擬表來調整實例,使用 SQL 語句跟蹤文件調整應用程序性能。 SQL 語言跟蹤工具將結果輸出成一個操作系統的文件,管理員可以使用 TKPROF 工具查看這些文件。
4 、 ORACLE Enterprise Manager ( OEM ),這是一個圖形的用戶管理界面,用戶可以使用它方便地進行數據庫管理而不必記住復雜的 ORACLE 數據庫管理的命令。
5 、 EXPLAIN PLAN——SQL 語言優化命令,使用這個命令可以幫助程序員寫出高效的 SQL 語言。
ORACLE 數據庫的系統性能評估
信息系統的類型不同,需要關注的數據庫參數也是不同的。數據庫管理員需要根據自己的信息系統的類型著重考慮不同的數據庫參數。
1 、在線事務處理信息系統( OLTP ),這種類型的信息系統一般需要有大量的 Insert 、 Update 操作,典型的系統包括民航機票發售系統、銀行儲蓄系統等。 OLTP 系統需要保證數據庫的并發性、可靠性和最終用戶的速度,這類系統使用的 ORACLE 數據庫需要主要考慮下述參數:
l???? l???? 數據庫回滾段是否足夠?
l???? l???? 是否需要建立 ORACLE 數據庫索引、聚集、散列?
l???? l???? 系統全局區( SGA )大小是否足夠?
l???? l???? SQL 語句是否高效?
2 、數據倉庫系統( Data Warehousing ),這種信息系統的主要任務是從 ORACLE 的海量數據中進行查詢,得到數據之間的某些規律。數據庫管理員需要為這種類型的 ORACLE 數據庫著重考慮下述參數:
l???? l???? 是否采用 B*- 索引或者 bitmap 索引?
l???? l???? 是否采用并行 SQL 查詢以提高查詢效率?
l???? l???? 是否采用 PL/SQL 函數編寫存儲過程?
l???? l???? 有必要的話,需要建立并行數據庫提高數據庫的查詢效率
SQL 語句的調整原則
SQL 語言是一種靈活的語言,相同的功能可以使用不同的語句來實現,但是語句的執行效率是很不相同的。程序員可以使用 EXPLAIN PLAN 語句來比較各種實現方案,并選出最優的實現方案。總得來講,程序員寫 SQL 語句需要滿足考慮如下規則:
1 、盡量使用索引。試比較下面兩條 SQL 語句:
語句 A : SELECT dname, deptno FROM dept WHERE deptno NOT IN?
(SELECT deptno FROM emp);
語句 B : SELECT dname, deptno FROM dept WHERE NOT EXISTS
(SELECT deptno FROM emp WHERE dept.deptno = emp.deptno);
這兩條查詢語句實現的結果是相同的,但是執行語句 A 的時候, ORACLE 會對整個 emp 表進行掃描,沒有使用建立在 emp 表上的 deptno 索引,執行語句 B 的時候,由于在子查詢中使用了聯合查詢, ORACLE 只是對 emp 表進行的部分數據掃描,并利用了 deptno 列的索引,所以語句 B 的效率要比語句 A 的效率高一些。
2 、選擇聯合查詢的聯合次序。考慮下面的例子:
SELECT stuff FROM taba a, tabb b, tabc c
WHERE a.acol between :alow and :ahigh
AND b.bcol between :blow and :bhigh
AND c.ccol between :clow and :chigh
AND a.key1 = b.key1
AMD a.key2 = c.key2;
這個 SQL 例子中,程序員首先需要選擇要查詢的主表,因為主表要進行整個表數據的掃描,所以主表應該數據量最小,所以例子中表 A 的 acol 列的范圍應該比表 B 和表 C 相應列的范圍小。
3 、在子查詢中慎重使用 IN 或者 NOT IN 語句,使用 where (NOT) exists 的效果要好的多。
4 、慎重使用視圖的聯合查詢,尤其是比較復雜的視圖之間的聯合查詢。一般對視圖的查詢最好都分解為對數據表的直接查詢效果要好一些。
5 、可以在參數文件中設置 SHARED_POOL_RESERVED_SIZE 參數,這個參數在 SGA 共享池中保留一個連續的內存空間,連續的內存空間有益于存放大的 SQL 程序包。
6 、 ORACLE 公司提供的 DBMS_SHARED_POOL 程序可以幫助程序員將某些經常使用的存儲過程 “ 釘 ” 在 SQL 區中而不被換出內存,程序員對于經常使用并且占用內存很多的存儲過程 “ 釘 ” 到內存中有利于提高最終用戶的響應時間。
CPU 參數的調整
CPU 是服務器的一項重要資源,服務器良好的工作狀態是在工作高峰時 CPU 的使用率在 90 %以上。如果空閑時間 CPU 使用率就在 90 %以上,說明服務器缺乏 CPU 資源,如果工作高峰時 CPU 使用率仍然很低,說明服務器 CPU 資源還比較富余。
使用操作相同命令可以看到 CPU 的使用情況,一般 UNIX 操作系統的服務器,可以使用 sar –u 命令查看 CPU 的使用率, NT 操作系統的服務器,可以使用 NT 的性能管理器來查看 CPU 的使用率。
數據庫管理員可以通過查看 v$sysstat 數據字典中 “CPU used by this session” 統計項得知 ORACLE 數據庫使用的 CPU 時間,查看 “OS User level CPU time” 統計項得知操作系統用戶態下的 CPU 時間,查看 “OS System call CPU time” 統計項得知操作系統系統態下的 CPU 時間,操作系統總的 CPU 時間就是用戶態和系統態時間之和,如果 ORACLE 數據庫使用的 CPU 時間占操作系統總的 CPU 時間 90 %以上,說明服務器 CPU 基本上被 ORACLE 數據庫使用著,這是合理,反之,說明服務器 CPU 被其它程序占用過多, ORACLE 數據庫無法得到更多的 CPU 時間。
數據庫管理員還可以通過查看 v$sesstat 數據字典來獲得當前連接 ORACLE 數據庫各個會話占用的 CPU 時間,從而得知什么會話耗用服務器 CPU 比較多。
出現 CPU 資源不足的情況是很多的: SQL 語句的重解析、低效率的 SQL 語句、鎖沖突都會引起 CPU 資源不足。
1 、數據庫管理員可以執行下述語句來查看 SQL 語句的解析情況:
SELECT * FROM V$SYSSTAT
WHERE NAME IN
('parse time cpu', 'parse time elapsed', 'parse count (hard)');
這里 parse time cpu 是系統服務時間, parse time elapsed 是響應時間,用戶等待時間
waite time = parse time elapsed – parse time cpu
由此可以得到用戶 SQL 語句平均解析等待時間= waite time / parse count 。這個平均等待時間應該接近于 0 ,如果平均解析等待時間過長,數據庫管理員可以通過下述語句
SELECT SQL_TEXT, PARSE_CALLS, EXECUTIONS FROM V$SQLAREA
ORDER BY PARSE_CALLS;
來發現是什么 SQL 語句解析效率比較低。程序員可以優化這些語句,或者增加 ORACLE 參數 SESSION_CACHED_CURSORS 的值。
2 、數據庫管理員還可以通過下述語句:
SELECT BUFFER_GETS, EXECUTIONS, SQL_TEXT FROM V$SQLAREA;
查看低效率的 SQL 語句,優化這些語句也有助于提高 CPU 的利用率。
3 、數據庫管理員可以通過 v$system_event 數據字典中的 “latch free” 統計項查看 ORACLE 數據庫的沖突情況,如果沒有沖突的話, latch free 查詢出來沒有結果。如果沖突太大的話,數據庫管理員可以降低 spin_count 參數值,來消除高的 CPU 使用率。
內存參數的調整
內存參數的調整主要是指 ORACLE 數據庫的系統全局區( SGA )的調整。 SGA 主要由三部分構成:共享池、數據緩沖區、日志緩沖區。
1 、 ?? 共享池由兩部分構成:共享 SQL 區和數據字典緩沖區,共享 SQL 區是存放用戶 SQL 命令的區域,數據字典緩沖區存放數據庫運行的動態信息。數據庫管理員通過執行下述語句:
select (sum(pins - reloads)) / sum(pins) "Lib Cache"? from v$librarycache;
來查看共享 SQL 區的使用率。這個使用率應該在 90 %以上,否則需要增加共享池的大小。數據庫管理員還可以執行下述語句:
select (sum(gets - getmisses - usage - fixed)) / sum(gets) "RowCache" from v$rowcache;
查看數據字典緩沖區的使用率,這個使用率也應該在 90 %以上,否則需要增加共享池的大小。
2 、 ?? 數據緩沖區。數據庫管理員可以通過下述語句:
SELECT name, value? FROM v$sysstat? WHERE name IN ('db block gets', 'consistentgets','physical reads');
來查看數據庫數據緩沖區的使用情況。查詢出來的結果可以計算出來數據緩沖區的使用命中率= 1 - ( physical reads / (dbblock gets + consistent gets) ) 。
這個命中率應該在 90 %以上,否則需要增加數據緩沖區的大小。
3 、 ?? 日志緩沖區。數據庫管理員可以通過執行下述語句:
select name,value from v$sysstat where name in ('redo entries','redo log spacerequests'); 查看日志緩沖區的使用情況。查詢出的結果可以計算出日志緩沖區的申請失敗率:
申請失敗率= requests/entries ,申請失敗率應該接近于 0 ,否則說明日志緩沖區開設太小,需要增加 ORACLE 數據庫的日志緩沖區。
2 、調整應用程序結構設計。這一部分也是在開發信息系統之前完成,程序員在這一步需要考慮應用程序使用什么樣的體系結構,是使用傳統的 Client/Server 兩層體系結構,還是使用 Browser/Web/Database 的三層體系結構。不同的應用程序體系結構要求的數據庫資源是不同的。
3 、調整數據庫 SQL 語句。應用程序的執行最終將歸結為數據庫中的 SQL 語句執行,因此 SQL 語句的執行效率最終決定了 ORACLE 數據庫的性能。 ORACLE 公司推薦使用 ORACLE 語句優化器( Oracle Optimizer )和行鎖管理器( row-level manager )來調整優化 SQL 語句。
4 、調整服務器內存分配。內存分配是在信息系統運行過程中優化配置的,數據庫管理員可以根據數據庫運行狀況調整數據庫系統全局區( SGA 區)的數據緩沖區、日志緩沖區和共享池的大小;還可以調整程序全局區( PGA 區)的大小。需要注意的是, SGA 區不是越大越好, SGA 區過大會占用 操作系統使用的內存而引起虛擬內存的頁面交換,這樣反而會降低系統。
5 、調整硬盤 I/O ,這一步是在信息系統開發之前完成的。數據庫管理員可以將組成同一個表空間的數據文件放在不同的硬盤上,做到硬盤之間 I/O 負載均衡。
6 、調整操作系統參數,例如:運行在 UNIX 操作系統上的 ORACLE 數據庫,可以調整 UNIX 數據緩沖池的大小,每個進程所能使用的內存大小等參數。
實際上,上述數據庫優化措施之間是相互聯系的。 ORACLE 數據庫性能惡化表現基本上都是用戶響應時間比較長,需要用戶長時間的等待。但性能惡化的原因卻是多種多樣的,有時是多個因素共同造成了性能惡化的結果,這就需要數據庫管理員有比較全面的計算機知識,能夠敏感地察覺到影響數據庫性能的主要原因所在。另外,良好的數據庫管理工具對于優化數據庫性能也是很重要的。
ORACLE 數據庫性能優化工具
常用的數據庫性能優化工具有:
1 、 ORACLE 數據庫在線數據字典, ORACLE 在線數據字典能夠反映出 ORACLE 動態運行情況,對于調整數據庫性能是很有幫助的。
2 、操作系統工具,例如 UNIX 操作系統的 vmstat , iostat 等命令可以查看到系統系統級內存和硬盤 I/O 的使用情況,這些工具對于管理員弄清出系統瓶頸出現在什么地方有時候很有用。
3 、 SQL 語言跟蹤工具( SQL TRACE FACILITY ), SQL 語言跟蹤工具可以記錄 SQL 語句的執行情況,管理員可以使用虛擬表來調整實例,使用 SQL 語句跟蹤文件調整應用程序性能。 SQL 語言跟蹤工具將結果輸出成一個操作系統的文件,管理員可以使用 TKPROF 工具查看這些文件。
4 、 ORACLE Enterprise Manager ( OEM ),這是一個圖形的用戶管理界面,用戶可以使用它方便地進行數據庫管理而不必記住復雜的 ORACLE 數據庫管理的命令。
5 、 EXPLAIN PLAN——SQL 語言優化命令,使用這個命令可以幫助程序員寫出高效的 SQL 語言。
ORACLE 數據庫的系統性能評估
信息系統的類型不同,需要關注的數據庫參數也是不同的。數據庫管理員需要根據自己的信息系統的類型著重考慮不同的數據庫參數。
1 、在線事務處理信息系統( OLTP ),這種類型的信息系統一般需要有大量的 Insert 、 Update 操作,典型的系統包括民航機票發售系統、銀行儲蓄系統等。 OLTP 系統需要保證數據庫的并發性、可靠性和最終用戶的速度,這類系統使用的 ORACLE 數據庫需要主要考慮下述參數:
l???? l???? 數據庫回滾段是否足夠?
l???? l???? 是否需要建立 ORACLE 數據庫索引、聚集、散列?
l???? l???? 系統全局區( SGA )大小是否足夠?
l???? l???? SQL 語句是否高效?
2 、數據倉庫系統( Data Warehousing ),這種信息系統的主要任務是從 ORACLE 的海量數據中進行查詢,得到數據之間的某些規律。數據庫管理員需要為這種類型的 ORACLE 數據庫著重考慮下述參數:
l???? l???? 是否采用 B*- 索引或者 bitmap 索引?
l???? l???? 是否采用并行 SQL 查詢以提高查詢效率?
l???? l???? 是否采用 PL/SQL 函數編寫存儲過程?
l???? l???? 有必要的話,需要建立并行數據庫提高數據庫的查詢效率
SQL 語句的調整原則
SQL 語言是一種靈活的語言,相同的功能可以使用不同的語句來實現,但是語句的執行效率是很不相同的。程序員可以使用 EXPLAIN PLAN 語句來比較各種實現方案,并選出最優的實現方案。總得來講,程序員寫 SQL 語句需要滿足考慮如下規則:
1 、盡量使用索引。試比較下面兩條 SQL 語句:
語句 A : SELECT dname, deptno FROM dept WHERE deptno NOT IN?
(SELECT deptno FROM emp);
語句 B : SELECT dname, deptno FROM dept WHERE NOT EXISTS
(SELECT deptno FROM emp WHERE dept.deptno = emp.deptno);
這兩條查詢語句實現的結果是相同的,但是執行語句 A 的時候, ORACLE 會對整個 emp 表進行掃描,沒有使用建立在 emp 表上的 deptno 索引,執行語句 B 的時候,由于在子查詢中使用了聯合查詢, ORACLE 只是對 emp 表進行的部分數據掃描,并利用了 deptno 列的索引,所以語句 B 的效率要比語句 A 的效率高一些。
2 、選擇聯合查詢的聯合次序。考慮下面的例子:
SELECT stuff FROM taba a, tabb b, tabc c
WHERE a.acol between :alow and :ahigh
AND b.bcol between :blow and :bhigh
AND c.ccol between :clow and :chigh
AND a.key1 = b.key1
AMD a.key2 = c.key2;
這個 SQL 例子中,程序員首先需要選擇要查詢的主表,因為主表要進行整個表數據的掃描,所以主表應該數據量最小,所以例子中表 A 的 acol 列的范圍應該比表 B 和表 C 相應列的范圍小。
3 、在子查詢中慎重使用 IN 或者 NOT IN 語句,使用 where (NOT) exists 的效果要好的多。
4 、慎重使用視圖的聯合查詢,尤其是比較復雜的視圖之間的聯合查詢。一般對視圖的查詢最好都分解為對數據表的直接查詢效果要好一些。
5 、可以在參數文件中設置 SHARED_POOL_RESERVED_SIZE 參數,這個參數在 SGA 共享池中保留一個連續的內存空間,連續的內存空間有益于存放大的 SQL 程序包。
6 、 ORACLE 公司提供的 DBMS_SHARED_POOL 程序可以幫助程序員將某些經常使用的存儲過程 “ 釘 ” 在 SQL 區中而不被換出內存,程序員對于經常使用并且占用內存很多的存儲過程 “ 釘 ” 到內存中有利于提高最終用戶的響應時間。
CPU 參數的調整
CPU 是服務器的一項重要資源,服務器良好的工作狀態是在工作高峰時 CPU 的使用率在 90 %以上。如果空閑時間 CPU 使用率就在 90 %以上,說明服務器缺乏 CPU 資源,如果工作高峰時 CPU 使用率仍然很低,說明服務器 CPU 資源還比較富余。
使用操作相同命令可以看到 CPU 的使用情況,一般 UNIX 操作系統的服務器,可以使用 sar –u 命令查看 CPU 的使用率, NT 操作系統的服務器,可以使用 NT 的性能管理器來查看 CPU 的使用率。
數據庫管理員可以通過查看 v$sysstat 數據字典中 “CPU used by this session” 統計項得知 ORACLE 數據庫使用的 CPU 時間,查看 “OS User level CPU time” 統計項得知操作系統用戶態下的 CPU 時間,查看 “OS System call CPU time” 統計項得知操作系統系統態下的 CPU 時間,操作系統總的 CPU 時間就是用戶態和系統態時間之和,如果 ORACLE 數據庫使用的 CPU 時間占操作系統總的 CPU 時間 90 %以上,說明服務器 CPU 基本上被 ORACLE 數據庫使用著,這是合理,反之,說明服務器 CPU 被其它程序占用過多, ORACLE 數據庫無法得到更多的 CPU 時間。
數據庫管理員還可以通過查看 v$sesstat 數據字典來獲得當前連接 ORACLE 數據庫各個會話占用的 CPU 時間,從而得知什么會話耗用服務器 CPU 比較多。
出現 CPU 資源不足的情況是很多的: SQL 語句的重解析、低效率的 SQL 語句、鎖沖突都會引起 CPU 資源不足。
1 、數據庫管理員可以執行下述語句來查看 SQL 語句的解析情況:
SELECT * FROM V$SYSSTAT
WHERE NAME IN
('parse time cpu', 'parse time elapsed', 'parse count (hard)');
這里 parse time cpu 是系統服務時間, parse time elapsed 是響應時間,用戶等待時間
waite time = parse time elapsed – parse time cpu
由此可以得到用戶 SQL 語句平均解析等待時間= waite time / parse count 。這個平均等待時間應該接近于 0 ,如果平均解析等待時間過長,數據庫管理員可以通過下述語句
SELECT SQL_TEXT, PARSE_CALLS, EXECUTIONS FROM V$SQLAREA
ORDER BY PARSE_CALLS;
來發現是什么 SQL 語句解析效率比較低。程序員可以優化這些語句,或者增加 ORACLE 參數 SESSION_CACHED_CURSORS 的值。
2 、數據庫管理員還可以通過下述語句:
SELECT BUFFER_GETS, EXECUTIONS, SQL_TEXT FROM V$SQLAREA;
查看低效率的 SQL 語句,優化這些語句也有助于提高 CPU 的利用率。
3 、數據庫管理員可以通過 v$system_event 數據字典中的 “latch free” 統計項查看 ORACLE 數據庫的沖突情況,如果沒有沖突的話, latch free 查詢出來沒有結果。如果沖突太大的話,數據庫管理員可以降低 spin_count 參數值,來消除高的 CPU 使用率。
內存參數的調整
內存參數的調整主要是指 ORACLE 數據庫的系統全局區( SGA )的調整。 SGA 主要由三部分構成:共享池、數據緩沖區、日志緩沖區。
1 、 ?? 共享池由兩部分構成:共享 SQL 區和數據字典緩沖區,共享 SQL 區是存放用戶 SQL 命令的區域,數據字典緩沖區存放數據庫運行的動態信息。數據庫管理員通過執行下述語句:
select (sum(pins - reloads)) / sum(pins) "Lib Cache"? from v$librarycache;
來查看共享 SQL 區的使用率。這個使用率應該在 90 %以上,否則需要增加共享池的大小。數據庫管理員還可以執行下述語句:
select (sum(gets - getmisses - usage - fixed)) / sum(gets) "RowCache" from v$rowcache;
查看數據字典緩沖區的使用率,這個使用率也應該在 90 %以上,否則需要增加共享池的大小。
2 、 ?? 數據緩沖區。數據庫管理員可以通過下述語句:
SELECT name, value? FROM v$sysstat? WHERE name IN ('db block gets', 'consistentgets','physical reads');
來查看數據庫數據緩沖區的使用情況。查詢出來的結果可以計算出來數據緩沖區的使用命中率= 1 - ( physical reads / (dbblock gets + consistent gets) ) 。
這個命中率應該在 90 %以上,否則需要增加數據緩沖區的大小。
3 、 ?? 日志緩沖區。數據庫管理員可以通過執行下述語句:
select name,value from v$sysstat where name in ('redo entries','redo log spacerequests'); 查看日志緩沖區的使用情況。查詢出的結果可以計算出日志緩沖區的申請失敗率:
申請失敗率= requests/entries ,申請失敗率應該接近于 0 ,否則說明日志緩沖區開設太小,需要增加 ORACLE 數據庫的日志緩沖區。
總結
以上是生活随笔為你收集整理的SQL性能优化应该考虑哪些?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是汽车?
- 下一篇: 塞纳为什么挂P挡不解锁?