資料庫的查詢優化
① 如何優化資料庫中數據的查詢
1.應盡量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null
可以在num上設置默認值0,確保表中num列沒有null值,然後這樣查詢:
select id from t where num=0
2.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。優化器將無法通過索引來確定將要命中的行數,因此需要搜索該表的所有行。
3.應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num=10 or num=20
可以這樣查詢:
select id from t where num=10
union all
select id from t where num=20
4.in 和 not in 也要慎用,因為IN會使系統無法使用索引,而只能直接搜索表中的數據。如:
select id from t where num in(1,2,3)
對於連續的數值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
5.盡量避免在索引過的字元數據中,使用非打頭字母搜索。這也使得引擎無法利用索引。
見如下例子:
SELECT * FROM T1 WHERE NAME LIKE 『%L%』
SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=』L』
SELECT * FROM T1 WHERE NAME LIKE 『L%』
即使NAME欄位建有索引,前兩個查詢依然無法利用索引完成加快操作,引擎不得不對全表所有數據逐條操作來完成任務。而第三個查詢能夠使用索引來加快操作。
6.必要時強制查詢優化器使用某個索引,如在 where 子句中使用參數,也會導致全表掃描。因為sql只有在運行時才會解析局部變數,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變數的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:
select id from t where num=@num
可以改為強制查詢使用索引:
select id from t with(index(索引名)) where num=@num
7.應盡量避免在 where 子句中對欄位進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
SELECT * FROM T1 WHERE F1/2=100
應改為:
SELECT * FROM T1 WHERE F1=100*2
SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=』5378』
應改為:
SELECT * FROM RECORD WHERE CARD_NO LIKE 『5378%』
SELECT member_number, first_name, last_name FROM members
WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21
應改為:
SELECT member_number, first_name, last_name FROM members
WHERE dateofbirth < DATEADD(yy,-21,GETDATE())
即:任何對列的操作都將導致表掃描,它包括資料庫函數、計算表達式等等,查詢時要盡可能將操作移至等號右邊。
8.應盡量避免在where子句中對欄位進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where substring(name,1,3)='abc'--name以abc開頭的id
select id from t where datediff(day,createdate,'2005-11-30')=0--『2005-11-30』生成的id
應改為:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
9.不要在 where 子句中的「=」左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。
10.在使用索引欄位作為條件時,如果該索引是復合索引,那麼必須使用到該索引中的第一個欄位作為條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應盡可能的讓欄位順序與索引順序相一致。
11.很多時候用 exists是一個好的選擇:
elect num from a where num in(select num from b)
用下面的語句替換:
select num from a where exists(select 1 from b where num=a.num)
SELECT SUM(T1.C1)FROM T1 WHERE(
(SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)
SELECT SUM(T1.C1) FROM T1WHERE EXISTS(
SELECT * FROM T2 WHERE T2.C2=T1.C2)
兩者產生相同的結果,但是後者的效率顯然要高於前者。因為後者不會產生大量鎖定的表掃描或是索引掃描。
② 如何進行資料庫查詢優化
建索引,用索引,優化索引,重要的事說三遍,另外可以用(EXPLAIN sql語句)查看執行語句是否使用索引
③ 怎樣改進資料庫的查詢性能
1、使你的資料庫結構規范化,但是不要求一定達到第三範式,為了顯示和列印目的可以有數據冗餘2、評估你的系統中對性能影響的關鍵處,減少被頻繁訪問的核心表的數量,並在這些核心
表上重點優化索引,表結構(盡量緊湊)。典型的核心表是代碼表。
3、對於統計類應用,如果可能應寫成觸發器和存儲過程,這樣就有可能把一個消耗大量時
間的統計運算分布到每INSERT,DELETE,或者UPDATE來處理,從而極大提高查詢類操作的速度。
查詢選擇群居索引最有效。其他索引也要針對業務進行選擇。由於維護索引也要消耗系
統資源和時間,所以過多的索引對性能是損害甚至是毫無效果的。
5、如果可能,可以利用大資料庫對SQL的一些特殊規定來進一步優化,比如查詢暗示。
6、適當選擇硬體,綜合考慮CPU,內存,I/O系統的性能,以當前的CPU,內存配置來看,
很多資料庫系統的瓶頸出在I/O系統上。所以如果有可能,最好使用RAID。
當然如果你有足夠的財力,可以買更好的伺服器,或者搞伺服器集群就更利害啦。
7、可能的話,盡量使用存儲過程,因為存儲過程的執行計劃可以重復使用,而且不需要
象普通由CLIENT提交的SQL那樣進行處理和編譯。
8、檢查你的應用程序設計,如果有可能,盡量減少查詢次數和在網路上往返的數據。為了
獲取少量欄位而寫SELECT * 對性能的損害也比較利害。
9、在應用程序中協調並發和一致性之間的矛盾。並不是所有業務都需要放在事務中。大量
業務是允許臟讀的,在不關鍵事務中使用臟讀,或者讀提交,可以大大降低DEADLOCK和
進程之間彼此等待的機會,從而把由於互相鎖定資源引起的等待降低到最小。
不要在事務執行中進行大量計算或者與用戶交互的操作,因為事務的執行在要求上是
不允許被打斷的原子操作(回滾是失敗的),所以事務應該多而短小。長事務會鎖住
很多資源比較長的時間,因此也比較容易導致其他進程對資源的等待和死鎖的機會。
10、評估你開發系統的關鍵業務,在很多資料庫系統對性能的要求是彼此矛盾的,比如OLTP
應用和DSS是不同的。DSS傾向於使用各種索引加快檢索速度,而大量的索引對OLTP則是負擔。
11、不要在應用程序中寫怪異的SQL 查詢,比如 WHERE money!40000,這樣的語句,這種
SQL查詢,資料庫的SQL優化器是無法進行優化的。
12、定期維護和管理你的資料庫系統,壓縮掉那些垃圾空間,很多資料庫系統執行類似
刪除,事務等操作的時候,並不回收無用的物理空間。所以,制定一份合理的資料庫
維護計劃,不要等日誌文件或者LOG文件越長越大的時候才去整理資料庫。
還有很多很多要注意的東西,。。。。。。
④ 怎麼提高資料庫查詢效率
提高查詢效率首先要想到的就是加索引,那什麼是索引呢?
MySQL索引的建立對於MySQL的高效運行是很重要的,索引可以大大提高MySQL的檢索速度。
打個比方,如果合理的設計且使用索引的MySQL是一輛蘭博基尼的話,那麼沒有設計和使用索引的MySQL就是一個人力三輪車。
索引分單列索引和組合索引。單列索引,即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引。組合索引,即一個索引包含多個列。
創建索引時,你需要確保該索引是應用在 SQL 查詢語句的條件(一般作為 WHERE 子句的條件)。
實際上,索引也是一張表,該表保存了主鍵與索引欄位,並指向實體表的記錄。
上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件。
建立索引會佔用磁碟空間的索引文件。
如何使用索引呢?
首先索引有窄索引和寬索引兩個概念,窄索引是指索引的列數為1~2,寬索引就是說索引的列數大於2。
因為窄索引的效率要高於寬索引,所以能用窄索引就不要使用寬索引。
那麼對單欄位索引和復合索引應該如何使用?
目錄
單欄位索引的情況:
復合索引的優勢:
兩者的比較:
單欄位索引的情況:
1.表的主鍵,外鍵必須有索引
2.數據量超過300的表應該有索引
3.經常與其他表進行連接的表,在連接欄位上應該建立索引
4.經常出現在where字句中的欄位,特點是大表的欄位,應該建立索引
5.索引應該建在選擇性高的欄位上
6.索引應該建在小欄位上,對於大的文本欄位甚至超長欄位,不要建立索引
7.盡量用單欄位索引代替復合索引,復合索引的建立需要仔細的斟酌
復合索引的優勢:
1.單欄位索引很少甚至沒有
2.復合索引的幾個欄位經常同時以AND的方式出現在where語句
當where語句中的條件是OR時,索引不起作用。
兩者的比較:
以一個sql語句來舉例:SELECT * FROM STUDENT WHERE SEX="男" AND SAGE=18;
若在sex 和 sage 兩個欄位分別創建了單欄位索引,mysql查詢每次只能使用一個索引,雖然對於未添加索引時使用全盤掃描,我們的效率提升了很多,但如果在sex 和 sage兩個欄位添加復合索引,效率會跟高,如: 創建(sex, age,teacher)的復合索引,那麼其實相當於創建了(area,age,teacher)、(area,age)、(area)三個索引,這被稱為最佳左前綴特性。
那對於兩者優缺點的比較:
1.對於具有2個用and連接條件的語句,且2個列之間的關聯度較低的情況下,復合索引有一定優勢。
2.對於具有2個用and連接條件的語句,且2個列之間的關聯度較高的情況下,復合索引有很大優勢。
3.對於具有2個用or連接條件的語句,單索引有一定優勢,因為這種情況下復合索引將會導致全表掃描,而前者可以用到indexmerge的優化。
以上就是如何提高查詢效率的全部內容,如果有幫助到你的話記得點個關注喲
⑤ 資料庫中查詢優化的目的是什麼
MRR 是 MySQL 針對特定查詢的一種優化手段。假設一個查詢有二級索引可用,讀完二級索引後要回表才能查到那些不在當前二級索引上的列值,由於二級索引上引用的主鍵值不一定是有序的,因此就有可能造成大量的隨機 IO,如果回表前把主鍵值給它排一下序,那麼在回表的時候就可以用順序 IO 取代原本的隨機 IO。
如果想關閉 MRR 優化的話,就要把優化器開關 mrr 設置為 off。
默認只有在優化器認為 MRR 可以帶來優化的情況下才會走 MRR,如果你想不管什麼時候能走 MRR 的都走 MRR 的話,你要把 mrr_cost_based 設置為 off,不過最好不要這么干,因為這確實是一個坑,MRR 不一定什麼時候都好,全表掃描有時候會更加快,如果在這種場景下走 MRR 就完成了。
MRR 要把主鍵排個序,這樣之後對磁碟的操作就是由順序讀代替之前的隨機讀。從資源的使用情況上來看就是讓 CPU 和內存多做點事,來換磁碟的順序讀。然而排序是需要內存的,這塊內存的大小就由參數 read_rnd_buffer_size 來控制。
⑥ 資料庫查詢有哪些優化方面
1 SQL查詢語句的重寫,對於一個查詢可以用多種查詢語句實現,但不同查詢語句的資料庫執行計劃是不同的,一旦不能夠使用索引或造成較大的內存佔用會導致性能下降,因此需要對查詢語句進行重寫優化,最典型的例子就是not in語句使用外連接方式實現來進行優化
2 創建合理的索引結構,根據查詢語句的中查詢條件,在關系表上建立相應的索引,如B+樹索引和hash索引
3 修改程序業務邏輯,有些功能如果使用SQL語句實現,不但SQL語句復雜,還將導致資料庫的負擔增加,因此可以將有些數據操作的業務邏輯放到應用層進行實現,就是通過java編程實現
4 修改資料庫伺服器相關參數,優化伺服器性能
⑦ 資料庫查詢優化問題
有2種方式!!
第一種:先查詢頁數據,然後再查詢總的數據條數,分成兩步,速度還可以
第二種:使用語句塊或
存儲過程
,輸出參數,也可以
起始補管你怎麼樣,都要做2步
但是千萬不要用
子查詢
來獲得數據條數哈,不然你就會蹦
⑧ 資料庫表數據量大怎麼優化查詢速度
下面以關系資料庫系統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、對查詢進行優化,應盡可能避免全表掃描
2、寫數據語句時盡可能減少表的全局掃描
3、不要在條件判斷時進行 算數運算
4、很多時候用 exists 代替 in 是一個好的選擇
5 論索引技巧
⑩ 資料庫中查詢優化的一般規律是什麼
查詢檢索的優化首先想到你檢索條件中的欄位是不是索引欄位,不是的話,建立索引
然後是sql語句的優化,select其實就是循環,循環的次數越多,檢索效率越慢,子查詢可以有,但是不要超過三層,超過三層,估計就是檢索sql有問題,要重新梳理邏輯
避免笛卡爾積,幾個表關聯的時候,要用主鍵或者邏輯主鍵去關聯
聚合函數的用法,要注意重復數據的過濾
where條件盡量寫詳細,條件越多,就能過濾掉更多的數據,這樣就會提高效率
對於百萬級別或者千萬級別的數據量的檢索,就不是sql優化那麼簡單了,要用到資料庫本身的一些優化機制,有些資料庫帶有臨時表,這是很好的優化方法
存儲過程也是可以優化sql的,一些循環或者條件判斷都可以用存儲過程來實現
純手打。。。。。。。。。。。。。。。。。。。。。。。。。大家可以補充