靜網PWA視頻評論

基於MySQL的查詢優化技術

2023年10月29日

- txt下載

豆利
摘要:隨著網絡數據量的增大,用戶對資料庫查詢的要求也越來越高,普通的查詢有時很難滿足要求,迫切需要對於MySQL語句實現優化,以提高查詢效率。其中最常用的是創建索引。本文介紹了常用的SQL語句優化查詢方式。
關鍵詞:查詢;優化;索引;SQL語句
中圖分類號:TP311        文獻標識碼:A
文章編號:1009-3044(2021)15-0035-02
1查詢速度慢的原因
資料庫查詢的首先是客戶端發出查詢請求,服務端接受請求,服務端處理後相關數據,再把結果返回給客戶端,從而完成查詢的過程。在整個查詢過程中,涉及很多相關的參數,比如網絡速度、內存容量、I/O吞吐率等等。其中查詢的數據量比較大,查詢語句沒有設計好,查詢語句沒有優化好,返回不必要的行和列,產生死鎖等,也常常是查詢慢的原因。
2優化查詢速度
對於MySQL查詢優化最主要的是需要建立高性能的索引。索引對於查詢達到良好的性能起到關鍵的作用,尤其是當數據表中的數據量越來越大,越來越多的時候,索引的作用就尤其重要,當然在數據量比較小的時候,不恰當的索引對於查詢性能還不明顯,當數據量增大的時候,性能就會急劇下降,效果較為顯著。所以,就利用了索引,資料庫的索引有助於加快查詢速度。
為了對資料庫索引速度進行驗證,需要資料庫及相應的數據表。
首先創建資料庫educ,在educ資料庫中創建表student,其創建代碼如下:
CREATE DATABASE educ;--創建資料庫
CREATE TABLE student(sid int, sname char(8),gender char(8),email varchar(56),depid char(10));--創建數據表student
CREATE TABLE department(depid char(10),depName varchar(40),num int);--創建數據表department
創建存儲過程,實現批量數據的插入,代碼如下:
DELIMITER $$         --聲明存儲過程的結束符為$$
CREATE PROCEDURE proc1()    --創建存儲過程
BEGIN
DECLARE i INT DEFAULT 1;
WHILE(i<=100000) DO
INSERT INTO student VALUES(i,Sophie,female,CONCAT(『Sophie,i,@hffe.cn));
SET i=i+1;
END WHILE;
END$$
DELIMITER;   ---重新聲明MySQL的結束符為;
查看存儲過程:SHOW CREATE PROCEDURE proc1;
調用存儲過程:CALL proc1;可以實現批量插入數據。
(1)使用聚合函數查詢出相應的結果,添加索引後驗證執行效率
未創建索引時:SELECT MAX(sid) FROM student;
結果耗時為:1 row in set<0.02 sec>。
創建索引後 CREATE INDEX index_sid cON  student(sid)後,先使用命令SET QUERY CACHE清除緩存信息,重新執行SQL命令,結果耗時為:1 row in set<0.00 sec>。以下執行語句之前,首先用SET QUERY CACHE清除緩存信息,再重新執行命令。
(2)在分組(GROUP BY)、排序(ORDER BY)之後的欄位進行添加索引。
未創建索引時:SELECT sid,COUNT(*) FROM student  GROUP BY sid;
結果耗時:5 row in set<0.03 sec>。
創建索引後:CREATE INDEX index_sid ON student(sid);重新執行SQL命令,結果耗時:
5 row in set<0.02 sec>。
(3)多表連接優化
對於多表連接查詢,不管幾張表實現查詢,都需要在連接欄位上建立索引,以加快查詢速度。
未創建索引時:SELECT sid,sname,gender,depname from student inner join department on stuent.depid=department.depid;
結果耗時:51 row in set<0.02 sec>。
創建索引後: 51 row in set<0.00 sec>。
對於子查詢中的IN子查詢會掃描整張表,需使用EXISTS子查詢代替使用,當然不是所有的索引都對查詢起顯著效果,MySQL是根據數據表中的數據進行優化的,當索引中有大量重複數據時,索引就失去了其顯著的作用,假設在gender欄位中值為male和female各占一半的時候,即使在gender上建立索引也不起作用。當然索引並不是越多越好,索引在加速查詢的同時,也有其弊端。索引是以文件的形式存儲的,索引文件需要占有磁碟空間。
若數據表中的索引很多的時候,查詢會很浪費時間,索引會降低增加、刪除、修改等相關數據操作,數據表中索引越多,索引更新的時間會越長。應儘量避免更新聚集索引數據列,因為聚集索引數據列的順序和表的物理記錄保持一致,一旦聚集索引的數據進行更新,將導致整張表的列值的改變,會增加很大的系統開銷。復合索引在使用的時候,一般以索引的第一個列值作為條件查詢,如果值相等,接著選擇第二個欄位列值進行排序,以此類推,否則建立的復合索引將不起作用。
如果索引定義的列值過長,這樣會讓索引變得很慢。通常以欄位列值開始的部分的字符作為索引,可以大大節約索引空間,提高索引效率。其中前綴索引指的是把欄位值的一部分作為索引,對於BLOB、TEXT、VARCHAR等類型必須使用前綴索引,畢竟索引需要存儲空間,索引太長,維護起來也相對困難。
對於MySQL語句中WHERE中的子查詢IN(),如希望搜索某個員工的工資情況,可以按照下面的方式實現查詢:
msql>SELECT *FROM  employees
->WHERE  員工編號 IN(
->SELECT 員工編號 FROM salary WHERE 員工編號=2020002);
對於IN子查詢,我們一般認為,存儲引擎是先執行裡面的子查詢,把查詢的結果返回,作為外查詢的條件,即外層查詢後執行。但是實際情況不是這樣的,MySQL會把外層表直接壓入子查詢中,MySQL認為這樣執行的效率會更高,也就是說MySQL實際把查詢改寫了這樣的形式:
mysql->SELECT *FROM employees
->WHERE EXISTS(
->SELECT *FROM salary WHERE 員工編號=2020002
->AND employees.員工編號=salary.員工編號);
這時子查詢需要根據員工編號來關聯外部表employees。通過explain 可以看出來,MySQL對employees表進行全表掃描,然後根據返回的員工編號逐一執行子查詢。
如果外部表是個很小的表,結果可能不會引起注意,但是如果外層的表是一個非常大的表,那麼這個in子查的性能就會比較糟糕。
當然我們還可以用下面的查詢重新改寫這個查詢:
mysql->SELECT *FROM employees
->INNER JOIN salary USING(員工編號)
->WHERE 員工編號=『2020002;
另一個優化辦法是通過連接函數GROUP_CONCAT()在IN()子查詢語句中構造一個由逗號分隔開來的列表序列,當然有的時候比使用關聯寫的效率更好些。一般情況下,不建議使用IN子查詢,畢竟執行效率相對低些,建議使用EXISTS()子查詢獲取更高的執行效率。下面是對於IN子查詢改寫的情況:
mysql->SELECT *FROM employees
->WHERE EXISTS(
->SELECT *FROM salary WHERE 員工編號=2020002
->AND employees.員工編號=salary.員工編號);
(4)需要在經常搜索的條件WHERE中涉及查詢的欄位中添加索引
在查詢的時候,儘量避免使用SELECT *FROM  abc;這樣的語句,儘量不要使用*,需要使用具體的欄位來顯示結果,這樣可以提高查詢效率。在查詢語句中,儘量避免在WHERE中使用空值進行判斷,比如SELECT *FROM abc WHERE 備註 IS NULL,如果執行這個查詢,就需要搜索abc整張表,可以修改為:把備註的空值利用默認值(DEFAULT)修改為0,即查詢語句為:SELECT *FROM abc WHERE 備註=0。
在WHERE條件中避免使用!=或<>等操作符,否則的話,就會導致存儲引擎掃描整張數據表。在WHERE子句中儘量避免使用OR進行連接條件,否則,也會導致存儲引擎掃描整張數據表。例如:SELECT *FROM employees WHERE 姓名=章三 OR 姓名=張宏,可以使用UNION聯合查詢,改進代碼如下:SELECT *FROM employees WHERE 姓名=章三UNION  SELECT
*FROM  employees WHERE 姓名=張宏。
在WHERE 條件查詢中,對於模糊查找,會導致掃描整張數據表,例如:SELECT id  FROM employees WHERE 姓名 LIKE『%adb%,若要考慮提高效率,可以用全文索引實現。
在SQL語句中也要避免局部變量的使用,會掃描整張數據表。因為局部變量的解析是在查詢的時候才進行的。例如:SELECT num FROM  a WHERE name=@name 就可以進行轉換為:SELECT num FROM a WITH(index(索引名字)) WHERE name=@name。
在查詢中,避免在WHERE條件中使用函數,函數的使用也會掃描整張數據表,例如:SELECT sid FROM a WHERE SUBSTRING(名稱,1,4)=abdc,欄位名稱的列值以abdc開頭的sid應改寫為:SELECT sid FROM a WHERE 名稱 LIKE 『abdc%,執行這樣的操作,查詢效率會相對提高些。
對於查詢優化,最根本的是表的結構設計要合理,在設計表中欄位時,若某些欄位能使用數值型的話,就儘量避免使用字符類型,若該欄位的列值中只含有數字信息,該欄位的數據類型就不要設計為字符型,這樣會降低查詢和連接的性能,增加開銷成本,這是因為存儲引擎在處理查詢連接時,會逐個字符進行比較,而對於數字型的,比較一次就足夠了。
3結束語
索引是加快查詢的重要方法,如果數據量很小,索引的作用不大,當數據量很大的時候,尤其涉及多個表連接時,索引的作用更大。當然索引也有弊端,就是占用磁碟空間,但這些弊端並不妨礙索引的應用,索引在資料庫中通常是必不可少的。
參考文獻:
[1] 周德偉,覃國蓉.MySQL資料庫技術[M].2版.北京:高等教育出版社,2019.
[2] Baron Scbwartz,Peter Zaitsev,Vadim Tkacbenko,等.高性能MySQL[M]. 北京:電子工業出版社,2013.
[3]韓兵,王照清,廖聯軍,等.基於MySQL多表分頁查詢優化技術[J].計算機系統應用,2016,25(8):171-175.
[4] 武洪萍,馬桂婷,等.MySQL資料庫原理及應用[M].北京:人民郵電出版社,2014.
[5] 張士軍,陸海倫,等. 索引在MySQL查詢優化中的應用[J]. 計算機與數字工程,2007,35(1):37-39,8.
[6] 王珊,薩師煊.資料庫系統概論[M].4版.北京:高等教育出版社,2006.
【通聯編輯:王力】

收藏

相關推薦
一種最大化吞吐量增益的D2D通信資源分配算法
EVS高清語音編解碼器對VoLTE覆蓋性能影響
平衡積分卡在海事規費征稽工作考評中的應用
流行音樂在初中音樂教學中的合理應用
黑龍江森工林區經濟轉型發展的動力因素分析
多種VOC共存評估法對飾面刨花板的危害性研究
響應面優化紫蘇籽油超聲提取工藝研究
城市道路設計思路與技術要點分析
斷層破碎帶隧道施工技術分析
結構物回填的施工
泵送混凝土裂縫產生的原因及解決的措施
高效液相色譜法測定食品中羅丹明B含量的不確定度評估
食品質檢報告的解讀及運用
郫縣安龍村全家河流域水景觀研究
初探地鐵項目的設備管理
公路路基高邊坡防護技術措施探討
超寬工程船遠洋運輸綁紮固定解決方案
蚌埠市政務外網地址V6改造方案設計
香椿發朋友圈的說說
失眠說說心情短語人生感悟
商業廣場環境中無線信道及其特性分析
基於計算思維的虛擬作業系統設計
試論商業銀行個人金融業務轉型發展的思考探究
為什麼ipad連上wifi卻上不了網
這些人絕對不能喝菊花茶
安徽房屋長期租賃合同書
我的2023年暑假計劃
淺談物理有效教學設計以機械波教學為例
小學英語語法重點知識匯總
2023年兔年不宜添丁 哪些屬相不適合生兔寶寶
消費時代中的文學反思
金工銑床實習報告範文
物理高考這十類容易發揮失常的考生,該如何「自救」?
個性網短句說說

清純唯美圖片大全

字典網 - 試題庫 - 元問答 - 简体 - 頂部

Copyright © cnj8 All Rights Reserved.