資料庫的優化查詢
⑴ 資料庫的查詢優化方法分析
盡量不要使用 or 使用or會引起全表掃描 將大大降低查詢效率
alice like % &abigale& % 會使索引不起作用(針對sqlserver)
經過實踐驗證 charindex()並不比前面加%的like更能提高查詢效率 並且charindex()會使索引失去作用(指sqlserver資料庫)
欄位提取要按照 需多少 提多少 的原則 避免 select * 盡量使用 select 欄位 欄位 欄位 實踐證明 每少提取一個欄位 數據的提取速度就會有相應的提升 提升的速度還要看您舍棄的欄位的大小來判斷
order by按聚集索引列排序效率最高 一個sqlserver數據表只能建立一個聚集索引 一般默認為ID 也可以改為其它的欄位
能使用exists和not exists盡量使用 避免使用in或not in
能使用表連接盡量使用 避免使用exists和not exists
SET NOCOUNT ON
正確使用UNION和UNION ALL
慎用SELECT DISTINCT
少用游標
使用表的別名(Alias)
當在SQL語句中連接多個表時 請使用表的別名並把別名前綴於每個Column上 這樣可以減少解析的時間並減少那些由Column歧義引起的語法錯誤
盡量少使用游標
原因很簡單;就是游標的演算法是最原始的計算機演算法(和for if等語句一樣 一條條搜索來算;效率極低);
而sql語句用的是集合運算;速度則快的多;如果用索引速度則很快(用了指針)
創建索引
a 聚集索引:
聚集索引是磁碟存儲和邏輯顯示是一樣的
mssql表的主鍵一般是聚集索引;主鍵(每一條記錄唯一確定);
創建的主鍵自動會是聚集索引;
如有一個非常大的表(有百萬行);很長時間磁碟存儲上會有類似碎片(磁碟填充率效率低;一般是頻繁刪除造成的);
要提高它的性能的最簡潔辦法是:把這個表的主鍵去掉再保存後;然後重新設主鍵再保存;
(這個表就會在磁碟上重新整理排序;性能當然會提高喲)
b 非聚集索引:
非聚集索引是在外面建立小的附加表(一種樹形結構;大多數是B或B+樹);
讀(遍歷select等sql語句)表特快;但寫(update;delete insert等sql語句)表性能會略微下降
針對數據量大的表建議非聚集索引不要超過 個(節省額外磁碟負擔)
不要給類似 性別 列創建索引
死鎖:
是指有線程在讀一條記錄;別的線程讀這條記錄就要等待;
在mssql中只要長期占那條記錄的線程去掉;死鎖就會解除
在mssql中鎖是針對每一行記錄(所以性能不錯)
經常產生鎖的原因有:
a 在sql語句中使用事務語句(特別是事務中當查詢比較耗時)
b 在前台的應用程序的connetion沖突(未關閉)
c 多表聯合查詢(尤其是在打開大的數據集時)
sql語句優化
a is null not or in 不會用索引
b 避免在索引列上使用計算或函數處理(索引會大失性能) 還有 % ;有的甚至會全失索引性能
c SELECT中避免使用 * (寧可把需要欄位列出來;而不要用*去把所有的欄位都列出來)
d 避免相關子查詢(select中套select)
e where的條件中 =>exists>in (指性能)
f order by group by having distinct 等語句要慎用(因為它們效率不高;它們是先把數據到臨時表中再進行處理的)
g 聚集索引如有 個欄位組成(tt 和tt );tt 在前面;where的條件中如只用tt 欄位來判斷;就會用到一半的聚集索引;
where的條件中如tt 和tt 欄位都用來判斷了;就會全用到聚集索引;
where的條件中如只用tt 欄位來判斷;就會用不到聚集索引了;
盡量不要使用TEXT數據類型
除非你使用TEXT處理一個很大的數據 否則不要使用它 因為它不易於查詢 速度慢 用的不好還會浪費大量的空間
一般的 VARCHAR可以更好的處理你的數據
盡量不要使用臨時表
盡量不要使用臨時表 除非你必須這樣做 一般使用子查詢可以代替臨時表 使用臨時表會帶來系統開銷
如果前台的代碼你是使用資料庫連接池而臨時表卻自始至終都存在 SQL Server提供了一些替代方案 比如Table數據類型
盡量少使用外鍵和觸發器
因為在mssql中這些功能的性能做得不是很好;隨便動一下表(它就會到相關的表去搞判斷;有很多情況並不需要);在後台消耗資源大
lishixin/Article/program/Oracle/201311/16744
⑵ 資料庫查詢優化
你要問什麼?分頁當然要用存儲過程了。
菜
⑶ 怎麼樣操作資料庫的查詢優化技術
在一個關系資料庫中提高和優化查詢方法。很多人都將資料庫看成神奇的聖人,即能夠解決人們提出的各種問題。任何關系資料庫都有一套解決查詢的規則,而各種關系資料庫查詢的過程稍有所區別,但是基本的操作思想和過程是一致的。本文將為你介紹查詢分析器解決查詢的方法和過程。查詢優化的目標在查看分析器查詢的步驟之前,理解查詢優化目標相當重要。顯然,查詢操作的其中一個目標是盡可能地減少使用資源。從資料庫的角度看,這就意味著盡可能地減少I/O操作的次數。在對I/O操作的判斷上,查詢分析器經常做出錯誤的結果。而I/O操作次數必須滿足磁碟的讀取容量。這樣從磁碟I/O讀取的角度看,必須做出合理的選擇條件。索引基於表格的索引是關系資料庫用於解決查詢的重要技術,也是資料庫同時預先將數據分類導入到多表格的方式。通過索引中的欄位和實際數據存放的指針可以完成以上的過程。除了集簇索引(Clustered Index),每一索引的使用都以磁碟容量作為代價。集簇索引是真正意義上與磁碟讀取和磁碟容量代價無關的方法,因為集簇索引是真正按照順序將數據存儲到表格。當使用一個索引,資料庫引擎必須執行兩個數據讀取,這兩個數據讀取是資料庫記錄所必需的。第一個數據被讀取到實際數據指針的索引。第二個數據被讀入到指針指定的位置。此時必須通過資料庫伺服器來查詢,所以考慮系統資源消耗是有必要的。這也是查詢分析器不使用索引的主要原因。在後面的部分中,即Covering Indices,你將學會不使用這兩種讀取的方法——然而,在很多時候使用索引即意味著每一記錄可以完成兩次讀取。統計頁統計頁(Statistics page)是SQL Server用於決定是否使用索引時必需的信息。每一索引都有一個信息表,以將表格所有數據的索引關鍵值分布告訴查詢優化器。統計頁可用於大致估計從一個查詢返回的行數。查詢分析器必須知道返回的行數,由此確定是否值得使用索引方式。如果查詢優化器從索引統計頁中得知將返回幾行,它就會選擇使用索引;如果從統計頁中得知將返回大數量的行數,索引查詢優化器將有可能使用一個表掃描來解決查詢。欄位順序當使用到索引時,欄位順序(Field order)代表眾多欄位的順序。當判斷是否使用索引時,伺服器必須從第一欄位到最後欄位掃描。任何與查詢無關的欄位都將該索引清除掉。當進行索引安排時,你應該將最經常使用到的查詢排列在索引最頂端,不屬於查詢范圍的欄位可以使查詢優化器忽略整個索引。 使用WHERE語句WHERE語句是確定索引的選擇語句的重要組成部分。WHERE語句過濾了顯示記錄的數量,也是查詢優化器查找索引值的最容易的方法。WHERE語句的使用方法有很多種,以下為通常使用到的幾種形式:匹配(相等)WHERE語句最為常用的例子就是一個記錄或多個記錄的匹配。當你指定一個特定欄位等於一個值時,查詢優化器將獲知它要查詢的索引入口,並識別滿足查詢條件的記錄。這就大大地過濾讀取記錄的數量,從而減少查詢所需要的時間。並且,查詢分析器將可找到包含與匹配操作有關的欄位索引的位置。大於或小於雖然匹配和相等是最為普通的選擇方式,而WHERE語句中的查詢范圍要求也是經常見到的。在這種情況下,查詢分析器獲知大於或者小於指定值的索引范圍。通常,查詢分析器可從多個獨立語句中確定被讀取的索引百分含量,並決定是否值得使用索引技術。函數在WHERE語句中使用函數可以限制索引查詢的范圍。查詢分析器的查詢結果難於確定,尤其在執行非常量欄位的時候。所以,使用WHERE語句的函數將盡可能減少查詢次數。使用ORDER BY語句一旦查詢分析器以WHERE語句來判斷,它將以ORDER BY語句而開始查詢。如果查詢優化器找到正確順序行的相應索引,並且這一索引與WHERE條件相符合,優化器將會直接使用到索引技術。為了方便使用索引,ORDER BY語句不應該包含不必要的欄位。查詢分析器不能識別一個欄位的表面意思,而ORDER BY語句可實現按照欄位來排序。由此,如果你的ORDER BY語句中包括欄位,優化器將會找到包含所有這些欄位的索引。在ORDER BY語句中列出每一欄位將有效地阻止查詢優化器使用索引。詳細索引(Covering indices)以上我提到查詢分析器使用索引也會帶來負面,所以有時候我們將不使用索引技術,特別是對於已經確定順序的索引。比如,如果你從一個用戶記錄中選擇User ID,First Name,LastName以及EmailAddress,你可獲得包含所有這些欄位的一個索引,然後查詢分析器可以直接使用索引並讀取數據表。此時,使用一個雙向對照表(cross reference table)將特別有用。你可以在一個方向上使用一個集簇索引,然後在相反方向建立一個帶有欄位的索引。這樣SQL伺服器的第一個方向上可以使用物理表查詢,而在相反方向上使用到索引技術。由於長關鍵字的原因,詳細索引需要額外的空間和更多的時間。然而,如果你有一個參考表,詳細索引能夠有助於查詢分析器更好地工作。幫助查詢優化器當你提交一個查詢之後,查詢分析器的執行都必須通過很多環節。這些環節將有助於快速地獲得結果。然而,通過在查詢中指定你所需要的內容和建立正確的索引,即幫助查詢優化器的操作,以上過程才能順利完成。
⑷ 超詳細MySQL資料庫優化
資料庫優化一方面是找出系統的瓶頸,提高MySQL資料庫的整體性能,而另一方面需要合理的結構設計和參數調整,以提高用戶的相應速度,同時還要盡可能的節約系統資源,以便讓系統提供更大的負荷.
1. 優化一覽圖
2. 優化
筆者將優化分為了兩大類,軟優化和硬優化,軟優化一般是操作資料庫即可,而硬優化則是操作伺服器硬體及參數設置.
2.1 軟優化
2.1.1 查詢語句優化
1.首先我們可以用EXPLAIN或DESCRIBE(簡寫:DESC)命令分析一條查詢語句的執行信息.
2.例:
顯示:
其中會顯示索引和查詢數據讀取數據條數等信息.
2.1.2 優化子查詢
在MySQL中,盡量使用JOIN來代替子查詢.因為子查詢需要嵌套查詢,嵌套查詢時會建立一張臨時表,臨時表的建立和刪除都會有較大的系統開銷,而連接查詢不會創建臨時表,因此效率比嵌套子查詢高.
2.1.3 使用索引
索引是提高資料庫查詢速度最重要的方法之一,關於索引可以參高筆者<MySQL資料庫索引>一文,介紹比較詳細,此處記錄使用索引的三大注意事項:
2.1.4 分解表
對於欄位較多的表,如果某些欄位使用頻率較低,此時應當,將其分離出來從而形成新的表,
2.1.5 中間表
對於將大量連接查詢的表可以創建中間表,從而減少在查詢時造成的連接耗時.
2.1.6 增加冗餘欄位
類似於創建中間表,增加冗餘也是為了減少連接查詢.
2.1.7 分析表,,檢查表,優化表
分析表主要是分析表中關鍵字的分布,檢查表主要是檢查表中是否存在錯誤,優化表主要是消除刪除或更新造成的表空間浪費.
1. 分析表: 使用 ANALYZE 關鍵字,如ANALYZE TABLE user;
2. 檢查表: 使用 CHECK關鍵字,如CHECK TABLE user [option]
option 只對MyISAM有效,共五個參數值:
3. 優化表:使用OPTIMIZE關鍵字,如OPTIMIZE [LOCAL|NO_WRITE_TO_BINLOG] TABLE user;
LOCAL|NO_WRITE_TO_BINLOG都是表示不寫入日誌.,優化表只對VARCHAR,BLOB和TEXT有效,通過OPTIMIZE TABLE語句可以消除文件碎片,在執行過程中會加上只讀鎖.
2.2 硬優化
2.2.1 硬體三件套
1.配置多核心和頻率高的cpu,多核心可以執行多個線程.
2.配置大內存,提高內存,即可提高緩存區容量,因此能減少磁碟I/O時間,從而提高響應速度.
3.配置高速磁碟或合理分布磁碟:高速磁碟提高I/O,分布磁碟能提高並行操作的能力.
2.2.2 優化資料庫參數
優化資料庫參數可以提高資源利用率,從而提高MySQL伺服器性能.MySQL服務的配置參數都在my.cnf或my.ini,下面列出性能影響較大的幾個參數.
2.2.3 分庫分表
因為資料庫壓力過大,首先一個問題就是高峰期系統性能可能會降低,因為資料庫負載過高對性能會有影響。另外一個,壓力過大把你的資料庫給搞掛了怎麼辦?所以此時你必須得對系統做分庫分表 + 讀寫分離,也就是把一個庫拆分為多個庫,部署在多個資料庫服務上,這時作為主庫承載寫入請求。然後每個主庫都掛載至少一個從庫,由從庫來承載讀請求。
2.2.4 緩存集群
如果用戶量越來越大,此時你可以不停的加機器,比如說系統層面不停加機器,就可以承載更高的並發請求。然後資料庫層面如果寫入並發越來越高,就擴容加資料庫伺服器,通過分庫分表是可以支持擴容機器的,如果資料庫層面的讀並發越來越高,就擴容加更多的從庫。但是這里有一個很大的問題:資料庫其實本身不是用來承載高並發請求的,所以通常來說,資料庫單機每秒承載的並發就在幾千的數量級,而且資料庫使用的機器都是比較高配置,比較昂貴的機器,成本很高。如果你就是簡單的不停的加機器,其實是不對的。所以在高並發架構里通常都有緩存這個環節,緩存系統的設計就是為了承載高並發而生。所以單機承載的並發量都在每秒幾萬,甚至每秒數十萬,對高並發的承載能力比資料庫系統要高出一到兩個數量級。所以你完全可以根據系統的業務特性,對那種寫少讀多的請求,引入緩存集群。具體來說,就是在寫資料庫的時候同時寫一份數據到緩存集群里,然後用緩存集群來承載大部分的讀請求。這樣的話,通過緩存集群,就可以用更少的機器資源承載更高的並發。
一個完整而復雜的高並發系統架構中,一定會包含:各種復雜的自研基礎架構系統。各種精妙的架構設計.因此一篇小文頂多具有拋磚引玉的效果,但是資料庫優化的思想差不多就這些了.
⑸ 資料庫中查詢優化的一般規律是什麼
查詢檢索的優化首先想到你檢索條件中的欄位是不是索引欄位,不是的話,建立索引
然後是sql語句的優化,select其實就是循環,循環的次數越多,檢索效率越慢,子查詢可以有,但是不要超過三層,超過三層,估計就是檢索sql有問題,要重新梳理邏輯
避免笛卡爾積,幾個表關聯的時候,要用主鍵或者邏輯主鍵去關聯
聚合函數的用法,要注意重復數據的過濾
where條件盡量寫詳細,條件越多,就能過濾掉更多的數據,這樣就會提高效率
對於百萬級別或者千萬級別的數據量的檢索,就不是sql優化那麼簡單了,要用到資料庫本身的一些優化機制,有些資料庫帶有臨時表,這是很好的優化方法
存儲過程也是可以優化sql的,一些循環或者條件判斷都可以用存儲過程來實現
純手打。。。。。。。。。。。。。。。。。。。。。。。。。大家可以補充
⑹ 資料庫查詢性能優化方式有哪些
1、1、調整數據結構的設計。這一部分在開發信息系統之前完成,程序員需要考慮是否使用ORACLE資料庫的分區功能,對於經常訪問的資料庫表是否需要建立索引等。
2、2、調整應用程序結構設計。這一部分也是在開發信息系統之前完成,程序員在這一步需要考慮應用程序使用什麼樣的體系結構,是使用傳統的Client/Server兩層體系結構,還是使用Browser/Web/Database的三層體系結構。不同的應用程序體系結構要求的資料庫資源是不同的。
3、3、調整資料庫SQL語句。應用程序的執行最終將歸結為資料庫中的SQL語句執行,因此SQL語句的執行效率最終決定了ORACLE資料庫的性能。ORACLE公司推薦使用ORACLE語句優化器(Oracle Optimizer)和行鎖管理器(row-level manager)來調整優化SQL語句。
4、4、調整伺服器內存分配。內存分配是在信息系統運行過程中優化配置的,資料庫管理員可以根據資料庫運行狀況調整資料庫系統全局區(SGA區)的數據緩沖區、日誌緩沖區和共享池的大小;還可以調整程序全局區(PGA區)的大小。需要注意的是,SGA區不是越大越好,SGA區過大會佔用操作系統使用的內存而引起虛擬內存的頁面交換,這樣反而會降低系統。
5、5、調整硬碟I/O,這一步是在信息系統開發之前完成的。資料庫管理員可以將組成同一個表空間的數據文件放在不同的硬碟上,做到硬碟之間I/O負載均衡。
6、6、調整操作系統參數,例如:運行在UNIX操作系統上的ORACLE資料庫,可以調整UNIX數據緩沖池的大小,每個進程所能使用的內存大小等參數。
實際上,上述資料庫優化措施之間是相互聯系的。ORACLE資料庫性能惡化表現基本上都是用戶響應時間比較長,需要用戶長時間的等待。但性能惡化的原因卻是多種多樣的,有時是多個因素共同造成了性能惡化的結果,這就需要資料庫管理員有比較全面的計算機知識,能夠敏感地察覺到影響資料庫性能的主要原因所在。另外,良好的資料庫管理工具對於優化資料庫性能也是很重要的。
ORACLE資料庫性能優化工具
常用的資料庫性能優化工具有:
1、1、ORACLE資料庫在線數據字典,ORACLE在線數據字典能夠反映出ORACLE動態運行情況,對於調整資料庫性能是很有幫助的。
2、2、操作系統工具,例如UNIX操作系統的vmstat,iostat等命令可以查看到系統系統級內存和硬碟I/O的使用情況,這些工具對於管理員弄清出系統瓶頸出現在什麼地方有時候很有用。
3、3、SQL語言跟蹤工具(SQL TRACE FACILITY),SQL語言跟蹤工具可以記錄SQL語句的執行情況,管理員可以使用虛擬表來調整實例,使用SQL語句跟蹤文件調整應用程序性能。SQL語言跟蹤工具將結果輸出成一個操作系統的文件,管理員可以使用TKPROF工具查看這些文件。
4、4、ORACLE Enterprise Manager(OEM),這是一個圖形的用戶管理界面,用戶可以使用它方便地進行資料庫管理而不必記住復雜的ORACLE資料庫管理的命令。
5、5、EXPLAIN PLAN——SQL語言優化命令,使用這個命令可以幫助程序員寫出高效的SQL語言。
ORACLE資料庫的系統性能評估
信息系統的類型不同,需要關注的資料庫參數也是不同的。資料庫管理員需要根據自己的信息系統的類型著重考慮不同的資料庫參數。
1、1、在線事務處理信息系統(OLTP),這種類型的信息系統一般需要有大量的Insert、Update操作,典型的系統包括民航機票發售系統、銀行儲蓄系統等。OLTP系統需要保證資料庫的並發性、可靠性和最終用戶的速度,這類系統使用的ORACLE資料庫需要主要考慮下述參數:
l l 資料庫回滾段是否足夠?
l l 是否需要建立ORACLE資料庫索引、聚集、散列?
l l 系統全局區(SGA)大小是否足夠?
l l SQL語句是否高效?
2、2、數據倉庫系統(Data Warehousing),這種信息系統的主要任務是從ORACLE的海量數據中進行查詢,得到數據之間的某些規律。資料庫管理員需要為這種類型的ORACLE資料庫著重考慮下述參數:
l l 是否採用B*-索引或者bitmap索引?
l l 是否採用並行SQL查詢以提高查詢效率?
l l 是否採用PL/SQL函數編寫存儲過程?
l l 有必要的話,需要建立並行資料庫提高資料庫的查詢效率
SQL語句的調整原則
SQL語言是一種靈活的語言,相同的功能可以使用不同的語句來實現,但是語句的執行效率是很不相同的。程序員可以使用EXPLAIN PLAN語句來比較各種實現方案,並選出最優的實現方案。總得來講,程序員寫SQL語句需要滿足考慮如下規則:
1、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、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、3、在子查詢中慎重使用IN或者NOT IN語句,使用where (NOT) exists的效果要好的多。
4、4、慎重使用視圖的聯合查詢,尤其是比較復雜的視圖之間的聯合查詢。一般對視圖的查詢最好都分解為對數據表的直接查詢效果要好一些。
5、5、可以在參數文件中設置SHARED_POOL_RESERVED_SIZE參數,這個參數在SGA共享池中保留一個連續的內存空間,連續的內存空間有益於存放大的SQL程序包。
6、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、3、資料庫管理員可以通過v$system_event數據字典中的「latch free」統計項查看ORACLE資料庫的沖突情況,如果沒有沖突的話,latch free查詢出來沒有結果。如果沖突太大的話,資料庫管理員可以降低spin_count參數值,來消除高的CPU使用率。
內存參數的調整
內存參數的調整主要是指ORACLE資料庫的系統全局區(SGA)的調整。SGA主要由三部分構成:共享池、數據緩沖區、日誌緩沖區。
1、 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) "Row Cache" from v$rowcache;
查看數據字典緩沖區的使用率,這個使用率也應該在90%以上,否則需要增加共享池的大小。
2、 2、 數據緩沖區。資料庫管理員可以通過下述語句:
SELECT name, value FROM v$sysstat WHERE name IN ('db block gets', 'consistent gets','physical reads');
來查看資料庫數據緩沖區的使用情況。查詢出來的結果可以計算出來數據緩沖區的使用命中率=1 - ( physical reads / (db block gets + consistent gets) )。
這個命中率應該在90%以上,否則需要增加數據緩沖區的大小。
3、 3、 日誌緩沖區。資料庫管理員可以通過執行下述語句:
select name,value from v$sysstat where name in ('redo entries','redo log space requests');查看日誌緩沖區的使用情況。查詢出的結果可以計算出日誌緩沖區的申請失敗率:
申請失敗率=requests/entries,申請失敗率應該接近於0,否則說明日誌緩沖區開設太小,需要增加ORACLE資料庫的日誌緩沖區。
⑺ 資料庫表數據量大怎麼優化查詢速度
下面以關系資料庫系統Informix為例,介紹改善用戶查詢計劃的方法。
1.合理使用索引
索引是資料庫中重要的數據結構,它的根本目的就是為了提高查詢效率。現在大多數的資料庫產品都採用IBM最先提出的ISAM索引結構。索引的使用要恰到好處,其使用原則如下:
●在經常進行連接,但是沒有指定為外鍵的列上建立索引,而不經常連接的欄位則由優化器自動生成索引。
●在頻繁進行排序或分組(即進行group by或order by操作)的列上建立索引。
●在條件表達式中經常用到的不同值較多的列上建立檢索,在不同值少的列上不要建立索引。比如在雇員表的「性別」列上只有「男」與「女」兩個不同值,因此就無必要建立索引。如果建立索引不但不會提高查詢效率,反而會嚴重降低更新速度。
●如果待排序的列有多個,可以在這些列上建立復合索引(compound index)。
●使用系統工具。如Informix資料庫有一個tbcheck工具,可以在可疑的索引上進行檢查。在一些資料庫伺服器上,索引可能失效或者因為頻繁操作而使得讀取效率降低,如果一個使用索引的查詢不明不白地慢下來,可以試著用tbcheck工具檢查索引的完整性,必要時進行修復。另外,當資料庫表更新大量數據後,刪除並重建索引可以提高查詢速度。
2.避免或簡化排序
應當簡化或避免對大型表進行重復的排序。當能夠利用索引自動以適當的次序產生輸出時,優化器就避免了排序的步驟。以下是一些影響因素:
●索引中不包括一個或幾個待排序的列;
●group by或order by子句中列的次序與索引的次序不一樣;
●排序的列來自不同的表。
為了避免不必要的排序,就要正確地增建索引,合理地合並資料庫表(盡管有時可能影響表的規范化,但相對於效率的提高是值得的)。如果排序不可避免,那麼應當試圖簡化它,如縮小排序的列的范圍等。
3.消除對大型錶行數據的順序存取
在嵌套查詢中,對表的順序存取對查詢效率可能產生致命的影響。比如採用順序存取策略,一個嵌套3層的查詢,如果每層都查詢1000行,那麼這個查詢就要查詢10億行數據。避免這種情況的主要方法就是對連接的列進行索引。例如,兩個表:學生表(學號、姓名、年齡……)和選課表(學號、課程號、成績)。如果兩個表要做連接,就要在「學號」這個連接欄位上建立索引。
還可以使用並集來避免順序存取。盡管在所有的檢查列上都有索引,但某些形式的where子句強迫優化器使用順序存取。下面的查詢將強迫對orders表執行順序操作:
SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008
雖然在customer_num和order_num上建有索引,但是在上面的語句中優化器還是使用順序存取路徑掃描整個表。因為這個語句要檢索的是分離的行的集合,所以應該改為如下語句:
SELECT * FROM orders WHERE customer_num=104 AND order_num>1001
UNION
SELECT * FROM orders WHERE order_num=1008
這樣就能利用索引路徑處理查詢。
4.避免相關子查詢
一個列的標簽同時在主查詢和where子句中的查詢中出現,那麼很可能當主查詢中的列值改變之後,子查詢必須重新查詢一次。查詢嵌套層次越多,效率越低,因此應當盡量避免子查詢。如果子查詢不可避免,那麼要在子查詢中過濾掉盡可能多的行。
5.避免困難的正規表達式
MATCHES和LIKE關鍵字支持通配符匹配,技術上叫正規表達式。但這種匹配特別耗費時間。例如:SELECT * FROM customer WHERE zipcode LIKE 「98_ _ _」
即使在zipcode欄位上建立了索引,在這種情況下也還是採用順序掃描的方式。如果把語句改為SELECT * FROM customer WHERE zipcode >「98000」,在執行查詢時就會利用索引來查詢,顯然會大大提高速度。
另外,還要避免非開始的子串。例如語句:SELECT * FROM customer WHERE zipcode[2,3]>「80」,在where子句中採用了非開始子串,因而這個語句也不會使用索引。
6.使用臨時表加速查詢
把表的一個子集進行排序並創建臨時表,有時能加速查詢。它有助於避免多重排序操作,而且在其他方面還能簡化優化器的工作。例如:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
AND cust.postcode>「98000」
ORDER BY cust.name
如果這個查詢要被執行多次而不止一次,可以把所有未付款的客戶找出來放在一個臨時文件中,並按客戶的名字進行排序:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
ORDER BY cust.name
INTO TEMP cust_with_balance
然後以下面的方式在臨時表中查詢:
SELECT * FROM cust_with_balance
WHERE postcode>「98000」
臨時表中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁碟I/O,所以查詢工作量可以得到大幅減少。
注意:臨時表創建後不會反映主表的修改。在主表中數據頻繁修改的情況下,注意不要丟失數據。
7.用排序來取代非順序存取
非順序磁碟存取是最慢的操作,表現在磁碟存取臂的來回移動。SQL語句隱藏了這一情況,使得我們在寫應用程序時很容易寫出要求存取大量非順序頁的查詢。
有些時候,用資料庫的排序能力來替代非順序的存取能改進查詢。
⑻ 資料庫的多表大數據查詢應如何優化
1.應盡量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:x0dx0aselect id from t where num is nullx0dx0a可以在num上設置默認值0,確保表中num列沒有null值,然後這樣查詢:x0dx0aselect id from t where num=0x0dx0a2.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。優化器將無法通過索引來確定將要命中的行數,因此需要搜索該表的所有行。x0dx0a3.應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:x0dx0aselect id from t where num=10 or num=20x0dx0a可以這樣查詢:x0dx0aselect id from t where num=10x0dx0aunion allx0dx0aselect id from t where num=20x0dx0a4.in 和 not in 也要慎用,因為IN會使系統無法使用索引,而只能直接搜索表中的數據。如:x0dx0aselect id from t where num in(1,2,3)x0dx0a對於連續的數值,能用 between 就不要用 in 了:x0dx0aselect id from t where num between 1 and 3x0dx0a5.盡量避免在索引過的字元數據中,使用非打頭字母搜索。這也使得引擎無法利用索引。 x0dx0a見如下例子: x0dx0aSELECT * FROM T1 WHERE NAME LIKE 『%L%』 x0dx0aSELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=』L』 x0dx0aSELECT * FROM T1 WHERE NAME LIKE 『L%』 x0dx0a即使NAME欄位建有索引,前兩個查詢依然無法利用索引完成加快操作,引擎不得不對全表所有數據逐條操作來完成任務。而第三個查詢能夠使用索引來加快操作。x0dx0a6.必要時強制查詢優化器使用某個索引,如在 where 子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變數,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變數的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:x0dx0aselect id from t where num=@numx0dx0a可以改為強制查詢使用索引:x0dx0aselect id from t with(index(索引名)) where num=@numx0dx0a7.應盡量避免在 where 子句中對欄位進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:x0dx0aSELECT * FROM T1 WHERE F1/2=100 x0dx0a應改為: x0dx0aSELECT * FROM T1 WHERE F1=100*2x0dx0aSELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=』5378』 x0dx0a應改為: x0dx0aSELECT * FROM RECORD WHERE CARD_NO LIKE 『5378%』x0dx0aSELECT member_number, first_name, last_name FROM members x0dx0aWHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21 x0dx0a應改為: x0dx0aSELECT member_number, first_name, last_name FROM members x0dx0aWHERE dateofbirth < DATEADD(yy,-21,GETDATE()) x0dx0a即:任何對列的操作都將導致表掃描,它包括資料庫函數、計算表達式等等,查詢時要盡可能將操作移至等號右邊。x0dx0a8.應盡量避免在where子句中對欄位進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:x0dx0aselect id from t where substring(name,1,3)='abc'--name以abc開頭的idx0dx0aselect id from t where datediff(day,createdate,-11-30')=0--『2005-11-30』生成的idx0dx0a應改為:x0dx0aselect id from t where name like 'abc%'x0dx0aselect id from t where createdate>=-11-30' and createdate<-12-1'x0dx0a9.不要在 where 子句中的「=」左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。x0dx0a10.在使用索引欄位作為條件時,如果該索引是復合索引,那麼必須使用到該索引中的第一個欄位作為條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應盡可能的讓欄位順序與索引順序相一致。x0dx0a11.很多時候用 exists是一個好的選擇:x0dx0aelect num from a where num in(select num from b)x0dx0a用下面的語句替換:x0dx0aselect num from a where exists(select 1 from b where num=a.num)x0dx0aSELECT SUM(T1.C1)FROM T1 WHERE( x0dx0a(SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0) x0dx0aSELECT SUM(T1.C1) FROM T1WHERE EXISTS( x0dx0aSELECT * FROM T2 WHERE T2.C2=T1.C2) x0dx0a兩者產生相同的結果,但是後者的效率顯然要高於前者。因為後者不會產生大量鎖定的表掃描或是索引掃描。
⑼ 淺談資料庫查詢優化的幾種思路
應盡量避免全表掃描,首先應考慮在 where 及 order by ,group by 涉及的列上建立索引
可以幫助選擇更好的索引和優化查詢語句, 寫出更好的優化語句。 通常我們可以對比較復雜的尤其是涉及到多表的 SELECT 語句, 把關鍵字 EXPLAIN 加到前面, 查看執行計劃。例如: explain select * from news;
用具體的欄位列表代替「*」 , 不要返回用不到的任何欄位。
mysql innodb上的理解。
1,不需要的欄位會增加數據傳輸的時間,即使mysql伺服器和客戶端是在同一台機器上,使用的協議還是tcp,通信也是需要額外的時間。
2,要取的欄位、索引的類型,和這兩個也是有關系的。舉個例子,對於user表,有name和phone的聯合索引,select name from user where phone= 12345678912 和 select * from user where phone= 12345678912 ,前者要比後者的速度快,因為name可以在索引上直接拿到,不再需要讀取這條記錄了。
3,大欄位,例如很長的varchar,blob,text。准確來說,長度超過728位元組的時候,會把超出的數據放到另外一個地方,因此讀取這條記錄會增加一次io操作。
比如from_unixtime(create_time) = 』2014-05-29』就不能使用到索引,原因很簡單,b+樹中存的都是數據表中的欄位值,但進行檢索時,需要把所有元素都應用函數才能比較,顯然成本太大。所以語句應該寫成create_time = unix_timestamp(』2014-05-29』);
使用 procere analyse()函數對表進行分析, 該函數可以對表中列的數據類型提出優化建議。 能小就用小。 表數據類型第一個原則是: 使用能正確的表示和存儲數據的最短類型。 這樣可以減少對磁碟空間、 內存、 cpu 緩存的使用。
使用方法: select * from 表名 procere analyse();
通過拆分表可以提高表的訪問效率。 有 2 種拆分方法
1.垂直拆分
把主鍵和一些列放在一個表中, 然後把主鍵和另外的列放在另一個表中。 如果一個表中某些列常用, 而另外一些不常用, 則可以採用垂直拆分。
2.水平拆分
根據一列或者多列數據的值把數據行放到二個獨立的表中。
創建中間表, 表結構和源表結構完全相同, 轉移要統計的數據到中間表, 然後在中間表上進行統計, 得出想要的結果。
選擇多核和主頻高的 CPU。
使用更大的內存。 將盡量多的內存分配給 MYSQL 做緩存。
4.3.1 使用磁碟陣列
RAID 0 沒有數據冗餘, 沒有數據校驗的磁碟陳列。 實現 RAID 0至少需要兩塊以上的硬碟, 它將兩塊以上的硬碟合並成一塊, 數據連續地分割在每塊盤上。
RAID1 是將一個兩塊硬碟所構成 RAID 磁碟陣列, 其容量僅等於一塊硬碟的容量, 因為另一塊只是當作數據「鏡像」。使用 RAID-0+1 磁碟陣列。 RAID 0+1 是 RAID 0 和 RAID 1 的組合形式。 它在提供與 RAID 1 一樣的數據安全保障的同時, 也提供了與 RAID 0 近似的存儲性能。
4.3.2 調整磁碟調度演算法
選擇合適的磁碟調度演算法, 可以減少磁碟的尋道時間
對 MySQL 自身的優化主要是對其配置文件 my.cnf 中的各項參數進行優化調整。 如指定 MySQL 查詢緩沖區的大小, 指定 MySQL 允許的最大連接進程數等。
它的作用是存儲 select 查詢的文本及其相應結果。 如果隨後收到一個相同的查詢, 伺服器會從查詢緩存中直接得到查詢結果。 查詢緩存適用的對象是更新不頻繁的表, 當表中數據更改後, 查詢緩存中的相關條目就會被清空。
⑽ 分布式資料庫的查詢優化
指在執行分布式查詢時選擇查詢執行計劃的方法和關系運算符的實現演算法。根據系統環境的不同,查詢優化所使用的演算法也有所不同,通常分為遠程廣域網環境和高速區域網環境,其區別主要在網路的帶寬。對於一元運算符可以採用集中式資料庫中的查詢優化方法。而對於二元運算符,由於涉及場地間的數據傳輸,因此必須考慮通信代價。分布式查詢中常見的連接運算執行策略包括:
(1)半連接方法:利用半連接運算的轉換方法R∞S=(RµS)∞S。假設場地1和場地2上分別有關系R和關系S,首先在S上執行連接屬性上的投影並將結果傳輸至場地1,在場地1上執行關系R與投影的連接操作,再將結果傳輸至場地2與關系S執行連接操作。這種方法能夠降低執行連接運算時的網路通信代價,主要適用於帶寬較低的遠程廣域網路。
(2)枚舉法方法:指枚舉關系運算符的物理執行計劃,通過對比執行計劃的代價選擇執行演算法的方法。其中,連接運算符的物理執行計劃包括嵌套循環方法、哈希連接法和歸並連接法。枚舉法主要適用於以磁碟IO代價為主的高速區域網環境。