首頁 資料庫 mysql教程 總結mysql處理許多資料時的一些最佳化查詢速度

總結mysql處理許多資料時的一些最佳化查詢速度

Apr 26, 2017 pm 02:03 PM
mysql 最佳化查詢

最近一段時間由於工作需要,開始關注針對Mysql數據庫的select查詢語句的相關優化方法,需要的朋友可以參考下

由於在參與的實際項目中發現當mysql表的數據量達到百萬時,普通SQL查詢效率直線下降,如果where中的查詢條件較多時,其查詢速度簡直無法容忍。曾經測試對一個包含400多萬筆記錄(有索引)的表執行一條條件查詢,其查詢時間竟然高達40幾秒,相信這麼高的查詢延時,任何用戶都會抓狂。因此如何提高sql語句查詢效率,顯得十分重要。以下是網路上流傳較廣泛的30種SQL查詢語句最佳化方法:

1、應盡量避免在where 子句中使用!=或<>運算子,否則將引擎放棄使用索引而進行全表掃描。

2、對查詢進行最佳化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。

3、應盡量避免在where 子句中對欄位進行null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:

select id from t where num is null
登入後複製

可以在num上設定預設值0,確保表中num列沒有null值,然後這樣查詢:

select id from t where num=0
登入後複製

4、盡量避免在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
登入後複製

5、下面的查詢也會導致全表掃描:(不能前置百分號)

select id from t where name like ‘�c%&#39;
登入後複製


若要提高效率,可以考慮全文檢索。

6、in 和not in 也要慎用,否則會導致全表掃描,如:

select id from t where num in(1,2,3)
登入後複製

對於連續的數值,能用between 就不要用in 了:

select id from t where num between 1 and 3
登入後複製

7、如果在where 子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變量,但最佳化程序不能將存取計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然 而,如果在編譯時建立存取計劃,變數的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:

select id from t where num=@num
登入後複製

可以改為強制查詢使用索引:

select id from t with(index(索引名)) where num=@num
登入後複製

8、應盡量避免在where 子句中對欄位進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:

select id from t where num/2=100
应改为:
select id from t where num=100*2
登入後複製

9、應盡量避免在where子句中對欄位進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:

select id from t where substring(name,1,3)=&#39;abc&#39;–name以abc开头的id
select id from t where datediff(day,createdate,&#39;2005-11-30′)=0–&#39;2005-11-30′生成的id
应改为:
select id from t where name like ‘abc%&#39;
select id from t where createdate>=&#39;2005-11-30′ and createdate<&#39;2005-12-1′
登入後複製

10、不要在 where 子句中的「=」左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。

11、在使用索引欄位作為條件時,如果該索引是複合索引,那麼必須使用到該索引中的第一個欄位作為條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應盡可能的讓字段順序與索引順序相一致。

12、不要寫一些沒有意義的查詢,如需要產生一個空表結構:
select col1,col2 into #t from t where 1=0
這類程式碼不會回傳任何結果集,但是會消耗系統資源的,應改成這樣:

create table #t(…)
登入後複製

13、很多時候用exists 代替in 是一個好的選擇:

select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)
登入後複製

#14 、並不是所有索引對查詢都有效,SQL是根據表中資料來進行查詢優化的,當索引列有大量資料重複時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那麼即使在sex上建了索引也對查詢效率起不了作用。

15、索引並不是越多越好,索引固然可以提高對應的select 的效率,但同時也降低了insert 及update 的效率,因為insert 或update 時有可能會重建索引,所以怎樣建索引需慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要。

16.應盡可能的避免更新clustered 索引資料列,因為clustered 索引資料列的順序就是表記錄的物理儲存順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若套用系統需要頻繁更新 clustered 索引資料列,那麼需要考慮是否應將索引建置為 clustered 索引。

17、盡量使用數字型字段,若只含數值資訊的字段盡量不要設計為字元型,這會降低查詢和連接的效能,並會增加儲存開銷。這是因為引擎在處理查詢和連接時會 逐個比較字串中每一個字符,而對於數字型而言只需要比較一次就夠了。

18、盡可能的使用varchar/nvarchar 代替char/nchar ,因為首先變長字段存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的字段內搜索效率顯然要高些。

19、任何地方都不要使用 select * from t ,用特定的字段列表代替“*”,不要返回用不到的任何字段。

20、盡量使用表格變數來取代臨時表。如果表變數包含大量數據,請注意索引非常有限(只有主鍵索引)。

21、避免經常建立和刪除臨時表,以減少系統表資源的消耗。

22、臨時表並非不可用,適當地使用它們可以使某些例程更有效,例如,當需要重複引用大型表或常用表中的某個資料集時。但是,對於一次性事件,最好使 用匯出表。

23、在新建臨時表時,如果一次插入資料量很大,那麼可以使用select into 代替create table,避免造成大量log ,以提高速度;如果資料量不大,為了緩和系統表的資源,應先create table,然後insert。

24、如果使用到了臨時表,在預存程序的最後務必將所有的臨時表明確刪除,先 truncate table ,然後 drop table ,這樣可以避免系統表的較長時間鎖定。

25、盡量避免使用遊標,因為遊標的效率較差,如果遊標操作的資料超過1萬行,那麼就應該考慮改寫。

26、使用基於遊標的方法或臨時表方法之前,應先尋找基於集的解決方案來解決問題,基於集的方法通常更有效。

27、與暫存表一樣,遊標並不是無法使用。對小型資料集使用 FAST_FORWARD 遊標通常要優於其他逐行處理方法,尤其是在必須引用幾個表格才能獲得所需的資料時。在結果集中包含「合計」的例程通常比使用遊標執行的速度快。如果開發時 間允許,基於遊標的方法和基於集的方法都可以嘗試一下,看看哪一種方法的效果更好。

28、在所有的預存程序和觸發器的開始處設定 SET NOCOUNT ON ,在結束時設定 SET NOCOUNT OFF 。無需在執行預存程序和觸發器的每個語句後向客戶端發送 DONE_IN_PROC 訊息。

29、盡量避免向客戶端回傳大數據量,若資料量過大,應考慮相應需求是否合理。

30、盡量避免大事務操作,提升系統並發能力。

以上是總結mysql處理許多資料時的一些最佳化查詢速度的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

MySQL:初學者的數據管理易用性 MySQL:初學者的數據管理易用性 Apr 09, 2025 am 12:07 AM

MySQL適合初學者使用,因為它安裝簡單、功能強大且易於管理數據。 1.安裝和配置簡單,適用於多種操作系統。 2.支持基本操作如創建數據庫和表、插入、查詢、更新和刪除數據。 3.提供高級功能如JOIN操作和子查詢。 4.可以通過索引、查詢優化和分錶分區來提升性能。 5.支持備份、恢復和安全措施,確保數據的安全和一致性。

mysql:簡單的概念,用於輕鬆學習 mysql:簡單的概念,用於輕鬆學習 Apr 10, 2025 am 09:29 AM

MySQL是一個開源的關係型數據庫管理系統。 1)創建數據庫和表:使用CREATEDATABASE和CREATETABLE命令。 2)基本操作:INSERT、UPDATE、DELETE和SELECT。 3)高級操作:JOIN、子查詢和事務處理。 4)調試技巧:檢查語法、數據類型和權限。 5)優化建議:使用索引、避免SELECT*和使用事務。

navicat premium怎麼創建 navicat premium怎麼創建 Apr 09, 2025 am 07:09 AM

使用 Navicat Premium 創建數據庫:連接到數據庫服務器並輸入連接參數。右鍵單擊服務器並選擇“創建數據庫”。輸入新數據庫的名稱和指定字符集和排序規則。連接到新數據庫並在“對象瀏覽器”中創建表。右鍵單擊表並選擇“插入數據”來插入數據。

phpmyadmin怎麼打開 phpmyadmin怎麼打開 Apr 10, 2025 pm 10:51 PM

可以通過以下步驟打開 phpMyAdmin:1. 登錄網站控制面板;2. 找到並點擊 phpMyAdmin 圖標;3. 輸入 MySQL 憑據;4. 點擊 "登錄"。

MySQL和SQL:開發人員的基本技能 MySQL和SQL:開發人員的基本技能 Apr 10, 2025 am 09:30 AM

MySQL和SQL是開發者必備技能。 1.MySQL是開源的關係型數據庫管理系統,SQL是用於管理和操作數據庫的標準語言。 2.MySQL通過高效的數據存儲和檢索功能支持多種存儲引擎,SQL通過簡單語句完成複雜數據操作。 3.使用示例包括基本查詢和高級查詢,如按條件過濾和排序。 4.常見錯誤包括語法錯誤和性能問題,可通過檢查SQL語句和使用EXPLAIN命令優化。 5.性能優化技巧包括使用索引、避免全表掃描、優化JOIN操作和提升代碼可讀性。

navicat怎麼新建連接mysql navicat怎麼新建連接mysql Apr 09, 2025 am 07:21 AM

可在 Navicat 中通過以下步驟新建 MySQL 連接:打開應用程序並選擇“新建連接”(Ctrl N)。選擇“MySQL”作為連接類型。輸入主機名/IP 地址、端口、用戶名和密碼。 (可選)配置高級選項。保存連接並輸入連接名稱。

navicat如何執行sql navicat如何執行sql Apr 08, 2025 pm 11:42 PM

在 Navicat 中執行 SQL 的步驟:連接到數據庫。創建 SQL 編輯器窗口。編寫 SQL 查詢或腳本。單擊“運行”按鈕執行查詢或腳本。查看結果(如果執行查詢的話)。

Navicat 連接數據庫錯誤代碼及解決辦法 Navicat 連接數據庫錯誤代碼及解決辦法 Apr 08, 2025 pm 11:06 PM

Navicat 連接數據庫時常見的錯誤及解決方案:用戶名或密碼錯誤(Error 1045)防火牆阻止連接(Error 2003)連接超時(Error 10060)無法使用套接字連接(Error 1042)SSL 連接錯誤(Error 10055)連接嘗試過多導致主機被阻止(Error 1129)數據庫不存在(Error 1049)沒有權限連接到數據庫(Error 1000)

See all articles