關于SQL優化這些你了解嗎?

背景

在當今這個互聯網的時代無非要解決兩大難題,其一是信息安全,其二就是數據的存儲。而信息安全則是在數據存儲的基礎之上。一個公司從剛開始成立到發展成一個有上百人甚至上千人團隊的時候,公司的業務量是呈上升趨勢,客戶及用戶也會越來越多;之前設計的表結構可能會顯得不合理,表與表之間的聯系沒有一個穩定的業務功能劃分,從而表現出來的是相關表的備用字段越來越不夠用甚至新加字段,最壞的情況就是不同業務表之間會有數據冗雜。從而暴露出一些設計的問題,這也就是SQL優化點之一:數據庫表結構設計的合理性。近年來大數據越來越火,而大數據也是為了解決數據的存儲的手段之一,其目的是從海量的數據中收集到有價值的信息然后存儲到數據庫中,因為數據量大傳統的數據庫無法儲存那么多的信息所以需要分析有價值的信息后再做決定是否持久化。

優化點

前提必備知識

學會是用explain關鍵詞查看SQL語句性能,explain好像是從MYSQL5.6.3開始支持 select、update、delete語句分析,之前只支持select語句。現在我們普遍都是用5.7,所以的話不需要太擔心。這里的話不詳細講如何解讀explain輸出的性能信息。

優化之一 - 從數據庫設計方面考慮

  • 表與表之間的業務聯系要明確:表之間其實是有業務聯系的,比如:class(primary key:class_id,所有班級信息表)、student(primary key:student_num,所有學生信息表)、student_class(primary key:stu_class_id,所有學生所在班級信息表)著三張表,如果現在需要一張老師對應哪個班級的班主任的信息表;那么此時正確的方法是:新建 teacher、teacher_class表,而不是直接把老師的信息插入到student表中然后用一個字段來標識是老師還是學生。可能你看到這個你會想 “我肯定會按正確的那種方式啊”,但是這只是舉一個例子,其實在實際項目開發過程中表與表結構往往不會那么單一,這個時候你就會犯錯誤而用字段標識。但是也不能說是不能用字段標識,這個要看字段標識的兩種信息對應的業務是否有交叉點來取舍。

  • 表字段盡量使用數值型:因為數值型字段在MySQL底層應用的時候相比string類型的話性能更好;具體為什么性能更好就需要了解MySQL底層機制了,反正記住這點就好。

  • 屬性盡量使用定長:以減少占用儲存空間;如果你定義了一個 order_id varchar(32) ,當在存儲的時候有一條記錄的order_id=20180910242360,此時order_id實際占用了14個字節但是這個字段的屬性長度是32,所以還有18個字節長度是無用的但卻占用著內存空間。

  • 建立合理的索引:索引就是用某種數據結構來查找對應的信息,從而減低時間復雜度提高查找效率。建立索引的前提也要明確,綜合考慮再打算是否需要建立索引,畢竟索引是需要占用存儲空間的,有時候犧牲的空間卻換不回時間。

優化之二 - 從SQL語句優化方面考慮

1. 盡量將要輸出的字段寫出來;不要使用?select?*?from?where?xxxxx?;這種形式的語句。我在這測試時是使用*代替,但是記住在生產環境上盡量將字段替代*。

2. 合理使用連表查詢;不僅是表的連接需要較大的內存消耗另外一方面如果表設計的不是很合理也會導致索引無效從而造成極壞的結果。

3. 查詢的時候要注意是否走索引:假如你在name列建立了一個 name_index索引,查詢你使用?name?Like'%xxxx'?或者?name?Like'%xxxx%'?這種模糊查詢,那么此時可能就不會走索引;你應該這樣 ?name?Like'xxxx%'?。以下就是實際的一個例子:  

建立索引:

--?為cust_third_acct?建立一個普通索引
alter?table
cust_info
add?index?cust_third_acct_index(cust_third_acct);
  1. 通過SQL查詢信息:?select?*?from?sp_tunnel_user?where?cust_third_acct?like'0200%'; ? 以下就是滿足查詢條件的部分信息

  2. 分析Like'%xxxx%'的查詢性能:?select?*?from?sp_tunnel_user?where?cust_third_acct?like'%0200%';??通過Explain性能分析命令可以知道:在這種查詢條件下并沒有執行索引,type=all表明該語句執行的時候進行的是全表掃描;雖然我們在?cust_third_acct? 這個字段建立了索引,但是?possible_keys=null?則說明了 用?like'%0200%'?這種形式的條件是一定無法使用到 ?cust_third_acct_index??這個索引。

  3. 分析Like'xxxx%'的查詢性能:?select?*?from?sp_tunnel_user?where?cust_third_acct?like'0200%';??與b查詢語句相比這個查詢的 ?possible_keys=cust_third_acct_index??,這說明這個語句可能會用到?cust_third_acct_index?這個索引,但是key=null表明在實際的執行過程中并沒有用到 ?cust_third_acct_index??索引;剛才我們也說了這種條件查詢只是可能會走索引但是不一定發生,這個跟MySQL的存儲引擎相關,但是我們使用的時候盡量以這種方式去查詢。

4. 使用索引遵循最佳左前綴特性,建立聯合索引的時候將常用的屬性放在左邊。比如:我們需在在一張表的 cust_id 和 cust_tp 建立一個聯合索引 cust_id_type,設定cust_id(不是唯一) 是比較常用的那么我們就將cust_id放在左邊。

建立聯合索引:

--?為cust_id與cust_tp建立一個聯合索引
alter?table
cust_info
add?index??cust_id_type(cust_id,cust_tp);

5.使用符合索引的時候需要注意:使用聯合索引需要從左往右不間斷,索引才會生效,也就是說聯合索引使用的時候必須要連續但不要求全部使用。如:以上4我們建立了一個??cust_id_type??索引,當我們在使用的時候如果where條件中只使用了 cust_id,那么也會走索引;如果where條件中只使用了 cust_tp,那么這條語句不會走索引,以下就是一個實例:

  1. select?*?from?sp_tunnel_user?where?cust_id='8888888888'?and cust_tp='04';? 當查詢條件用到cust_id與cust_tp兩個字段并且cust_id在前面的時候,就會用到聯合索引;通過 key=cust_id_type可以看到實際執行過程中是用到索引了的。

  2. select?*?from?sp_tunnel_user?where?cust_id='8888888888'?;? 當查詢條件只用到cust_id一個字段時,也用到了聯合索引;通過 key=cust_id_type可以看到實際執行過程中是用到索引了的,這就是左前綴原則。

  3. select?*?from?sp_tunnel_user?where?cust_tp='04'?;??當查詢條件只用到cust_tp一個字段時,但卻沒有用到索引;通過 key=null 可以看到實際執行過程并沒有用到索引,這也是左前綴原則。


優化之三?- 讀寫分離與分庫分表

當數據量達到一定的數量之后,限制數據庫存儲性能的就不再是數據庫層面的優化就能夠解決的;這個時候往往采用的是讀寫分離與分庫分表同時也會結合緩存一起使用,而這個時候數據庫層面的優化只是基礎。讀寫分離適用于較小一些的數據量;分表適用于中等數據量;而分庫與分表一般是結合著用,這就適用于大數據量的存儲了,這也是現在大型互聯網公司解決數據存儲的方法之一。至于怎么讀寫分離、怎么分表、怎么分庫,這里不做過多的闡述后續文章會有相關知識分享。

原文出處:https://www.cnblogs.com/wind-june/p/9638356.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272396.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272396.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272396.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

圖片安全保護(未啟動)

圖片安全保護(未啟動) 圖片安全保護(未啟動)posted on 2016-01-27 22:54 代碼35 閱讀(...) 評論(...) 編輯 收藏 轉載于:https://www.cnblogs.com/xinglizhenchu/p/5164847.html

微機總線地址,物理地址 ,虛擬地址

總線地址 地址總線 (Address Bus;又稱:位址總線) 屬于一種電腦總線 (一部份),是由CPU 或有DMA 能力的單元,用來溝通這些單元想要存取(讀取/寫入)電腦內存元件/地方的實體位址。 自己…

Navicat遠程連接linux下mysql服務器1045錯誤解決辦法在這兒

1:首先通過xshell工具或者你熟悉的工具連接遠程linux下的服務器 mysql -uroot -p 然后輸入密碼 2.進行授權 如果想root用戶使用password從任何主機連接到mysql服務器的話。 GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIED BY 你的mysql密碼 WITH GRANT O…

內存劃分

一、內存分配 一個由C/C編譯的程序占用的內存分為以下幾個部分 1、棧區(stack): 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧。 2、堆區(heap&a…

樹莓派 博通BCM2835芯片手冊

手冊提取鏈接 鏈接:https://pan.baidu.com/s/1fdmIBNn1Pr1j3-ercNhKJg 提取碼:8y1b 驅動的兩大利器: 1、電路圖:通過電路圖找到寄存器 2、芯片手冊 樹莓派有54個通用IO口(0到53),所有GPIO口至少有兩個可選功能(輸入輸…

MVC實現實現文件流打包成壓縮包

MVC實現實現文件流打包成壓縮包1、使用壓縮類庫SharpZipLib SharpZipLib 是一款比較經典實用C#壓縮類庫SharpZipLib 庫特點:功能豐富、穩定 ,支持主流 zip、Gzip Tar BZip2 格式2、項目中引用SharpZipLib的官方地址是:http://icsharpcode.git…

Intellij idea 報錯:Error : java 不支持發行版本5

idea運行出現了這個錯誤 解決辦法按下圖所示:

屬性“dataProvider”有多個初始值設定項。(注意:“dataProvider”是“mx.charts.BarChart”的默認屬性)。...

1、錯誤描寫敘述 屬性“dataProvider”有多個初始值設定項。&#xff08;注意:“dataProvider”是“mx.charts.BarChart”的默認屬性&#xff09;。2、錯誤原因 <?xml version"1.0" encoding"utf-8"?> <s:Application xmlns:fx"http://ns.…

IO口操控代碼

我們在編寫驅動程序的時候&#xff0c;IO空間的起始地址是0x3f000000,加上GPIO的偏移量0x2000000,所以GPIO的物理地址應該是從0x3f200000開始的&#xff0c;然后在這個基礎上進行Linux系統的MMU內存虛擬化管理&#xff0c;映射到虛擬地址上。 底層驅動代碼 #include <linu…

C#一些實用的函數

1.DateTime 轉為Unix的long的時間戳long orderTime order.AddTime.ToUnixTimeStamp("Milliseconds");long payTime order.StartTime.Value.ToUnixTimeStamp("Milliseconds");2、獲取客戶端IP/// <summary>/// 獲取調用方的IP地址/// </summary&…

Vscode如何新建html文件

1、點擊Open Folder&#xff1a; 2、選擇目標文件夾&#xff0c;在本地新建一個拓展名為html的文件&#xff1a; 3、在第1行輸入!&#xff08;英文狀態下&#xff09;&#xff0c;按tab鍵&#xff0c;新建成功。界面如下圖所示&#xff1a;

混合app

cordova run android 把應用發送到手機ionic serve 電腦瀏覽器調試命令創建&#xff1a;cordova create hello com.example.hello HelloWorldcd hellocordova platform add androidcordova build androidcordova emulate android查詢cordova platform lscord…

vscode瀏覽器打開html

1.點擊拓展 2.輸入open in browser&#xff0c;選擇第一個 3.點擊安裝

VMware虛擬機克隆CentOS后網卡修改方法

轉自:http://www.linuxidc.com/Linux/2015-03/114975.htm 轉載于:https://www.cnblogs.com/water-sky/p/5169107.html

NET Core入門筆記

一、NET Core概念.NET Core 是開放源代碼通用開發平臺&#xff0c;由 Microsoft 和 .NET 社區在 GitHub 上共同維護。 它跨平臺&#xff08;支持 Windows、macOS 和 Linux&#xff09;&#xff0c;并且可用于生成設備、云和 IoT 應用程序。&#xff08;MSDN&#xff09;二、NET…

解決redis-cli連接時出現Could not connect to Redis at 127.0.0.1:6379: Connection refused

解決redis-cli連接時Could not connect to Redis at 127.0.0.1:6379: Connection refused 原因&#xff1a;服務端未啟動 [rootlocalhost bin]# ./redis-server redis.conf [rootlocalhost bin]# redis-cli -bash: redis-cli: 未找到命令 [rootlocalhost bin]# ./redis-cli 1…

ASP.NET MVC的過濾器筆記

過濾器概念APS.NET MVC中&#xff08;以下簡稱“MVC”&#xff09;的每一個請求&#xff0c;都會分配給相應的控制器和對應的行為方法去處理&#xff0c;而在這些處理的前前后后如果想再加一些額外的邏輯處理。這時候就用到了過濾器。1、過濾器&#xff08;Filters&#xff09;…

51單片機點亮第一個LED教程

單片機芯片型號&#xff1a; STC89C52 建立工程文件 打開keil4軟件界面如下&#xff1a; 新建工程文件&#xff08;自己選擇文件路徑&#xff0c;并給工程命名&#xff09;&#xff1a; 若出現下圖點擊OK&#xff1a; 然后選擇Atmel點擊OK&#xff08;根據自己的芯片型號選擇…

linux環境下用docker安裝rabbitmq

1、進入docker hub鏡像 倉庫地址&#xff1a;https://hub.docker.com/ 2、搜索rabbitMq&#xff0c;進入官方 的鏡像可以&#xff0c;看到以下幾種類型的鏡像&#xff1b;我們選擇帶有“mangement”的版本&#xff08;包含web管理頁面&#xff09;&#xff1b; 3、拉取鏡像 …

EF使用CodeFirst創建數據庫和表

EF支持三種實體模型&#xff1a;Code First&#xff0c;Model First和DB First&#xff0c;分別表示代碼優先&#xff0c;模型優先和數據庫優先。目前就個人來說使用CodeFirst最多&#xff0c;對此相對比較熟悉&#xff0c;先寫下Code First的使用吧。那什么是Code First代碼優…