一條SQL語句的奇妙旅程

来源:https://www.cnblogs.com/alkaid96/archive/2020/06/18/13160056.html
-Advertisement-
Play Games

MySQL的邏輯架構  連接器:負責用戶的身份認證和許可權校驗。 查詢緩存:這個在8.0以後的版本已經取締了,但是不影響設計思想的瞭解,即:當有一個SQL進來的時候,先會去匹配SQL語句,如果本地已經有緩存,即直接讀緩存,返回結果。乍一聽挺好的功能,為什麼會被取締呢?這存在一些設計理念的問題,MyS ...


MySQL的邏輯架構

  1.  連接器:負責用戶的身份認證和許可權校驗。

  2. 查詢緩存:這個在8.0以後的版本已經取締了,但是不影響設計思想的瞭解,即:當有一個SQL進來的時候,先會去匹配SQL語句,如果本地已經有緩存,即直接讀緩存,返回結果。乍一聽挺好的功能,為什麼會被取締呢?這存在一些設計理念的問題,MySQL追求極高的性能,該功能在實際使用過程中弊大於利,寫緩存/清緩存的過程可能會大幅度影響性能

  3. 分析器/解析器:這個模塊主要是進行一些語法分析/詞法分析,大家可能覺得與自己關係不太大,其實我們初學SQL語句的時候第一個打交道的就是這個模塊,比如當你輸入錯誤語句的時候,語法的錯誤在這層就已經發現了。

  4. 預處理器:這個模塊會確定你輸入的表和列是否真實存在,欄位別名是否有歧義,主要是當你語法沒錯的時候,確定是否符合這個場景。

  5. 查詢優化器:這可以說是server層最核心也是實戰最重要的地方了,首先,我們每次可以通過explain+sql來查看當前語句的各個屬性,這些屬性能給我們調優很好的建議。這點會在下篇文章中細談,這篇文章總體是為了打通全鏈路。
    其次,我們可以根據show warnings來查看查詢優化器到底做了哪些優化,從而考慮優化是否得當。

  6. 執行引擎:這塊主要是對結果進行過濾和排序,這個模塊的命名有些歧義,其實真實的數據檢索並非在這裡進行,這層進行的是對檢索的結果集進行一次過濾和排序。

  7. 存儲引擎:這裡就是真正的核心了,也就是我們一直所說的innodb、myisam等存儲引擎工作的地方,我們所有的查詢檢索任務都是在這裡進行的,所有的存儲也是在這裡進行。這個模塊也會在之後的文章中分析。

現在來假設一條SQL來做全套了,那麼它會是怎樣的一個邏輯呢?

首先我們客戶端與伺服器之間會建立一個連接(這裡的連接是指那幾種進程通信方式中的一種,大部分情況下說的是TCP/IP進行連接的,過程中需要我們mysql -u root -p輸入密碼,就可以進入mysql。

此時我們可以通過SQL語句進行增刪改查,當我們輸入一條語句,倘若在5.8版本之前,這條語句會進入查詢緩存,在這個模塊中先對SQL語句進行匹配,倘若找到完全匹配的緩存,則讀緩存返回結果,倘若沒有匹配的,則會進入下一模塊。查詢到的結果會寫進寫緩存這也是之所以在5.8以後取締掉查詢緩存的原因:寫緩存對性能是有一定的影響的,事實上這個影響甚至大於其對速度的提升。

進入下一模塊以後,會對語句進入一些詞法分析和語法分析,看看有沒有語法上的錯誤,初學者經常被卡在這個模塊,因為語句寫的不規範之類的問題。

再到後來,這條語句會進入預處理器,也就是看看你雖然說的都對,語法都對,但是你搜索的列如果是我根本沒有的,那相當於什麼都沒有,如果一切正常,就再往後走。

此時進入了server層最核心的查詢優化器,這裡MySQL有自己的想法, 他會對你輸入的語句進行一些優化和重排,這裡有一個很細節但是很核心的點:任何關聯進入查詢優化器都會變成嵌套迴圈關聯,也就是說,很多複雜的關聯都會變成類似於左連接之類的關聯,其原因也非常簡單,正如上述:執行引擎是對結果進行過濾和排序,那麼如果我們可以通過優化語句提前對語句進行過濾,這樣就可以大幅度提高性能。當我們查詢Explain+sql語句的時候會出現很多的屬性,我們需要註意的是要避免外部排序的產生,因為這樣會產生巨大的性能影響。

查詢優化器畢竟不是十全十美的,它的很多優化可能是好心沒做好事,最典型的就是臨時表了,首先臨時表這個東西本身是非常好的,它將中間過程的一些結果集存儲在記憶體上,很有利於查詢過程的執行,但是有可能記憶體不足的情況下,會將數據存儲在磁碟上,而磁碟參與讀寫一定會帶來非必要的資源和性能消耗,因此我們必須結合實際情況考究某些屬性的存在是否合理。

查詢優化器之後,查詢進入了執行引擎,在這裡其實並未進行太多的事情,執行引擎主要是調度存儲引擎,然後存儲引擎在硬碟中去檢索,然後拿到結果返回執行引擎,由執行引擎進行結果的過濾和排序,然後返回結果集回到客戶端,如果是在5.8以前的話,會放入寫緩存。

接下來就是核心的問題了:存儲引擎。

我們常用的存儲引擎大概是innodb和myisam,這兩任預設引擎撐起了MySQL的半邊天,現在我會比較粗略的介紹一下兩個引擎,詳細的文章會在後期輸出。

innodb存儲引擎與myisam存儲引擎

首先我們先認識所謂存儲引擎最重要的兩個功能就是存儲與查詢,那麼我們從存儲和查詢兩個方面來分析一下這兩個引擎的特點。

存儲方面:
首先當我們存儲數據的時候,因為這兩個引擎都是基於磁碟的,innodb是將索引和數據放在一起的,這跟其索引結構有關,當進行存儲的時候,innodb將所有的數據都存儲在一起;而myisam則是將索引數據和真實數據分開存儲,這樣其實是通過索引進行檢索,得到的結果是一個真實數據的指針,然後進入數據文件中進行隨機io。這就決定了一點,如果我們是innodb存儲引擎的話,主鍵儘量自增,因為如果非自增,會導致不能進行順序io,性能會有很大的退化。而myisam的數據存儲位置不能輕易移動,因為這樣會導致索引失效,也會影響性能。

查詢方面:
查詢就像翻詞典一樣,索引就像目錄和頁碼,這是非常重要的一部分,很多初學者覺得自己非常少用到索引,其實不然,我們經常用到的主鍵便是最標準的索引,當你的查詢命中索引的時候,便可以進入高速列車,為什麼呢?因為數據結構,在此強調一下,一直很認同程式=數據結構+演算法,數據結構非常重要,如果我們能命中索引,就可以進入索引的數據結構,此時要麼是哈希索引,要麼是b+樹索引,這兩種索引一個的複雜度為O(1),一個是O(log(M)N),其中M為索引關鍵字,N為總關鍵字數量,很容易看到,這種速度比全表遍歷好了太多了,所以如果命中索引的話,就可以大幅度提高速率。

當然這兩點雖然重要,但是都不是兩種引擎最大的區別,這兩種存儲引擎最大的差別在於事務性和鎖的粒度上,這也是innodb彎道超車最重要的原因。

事務性

隨著資料庫的應用場景越來越多,我們對數據的安全性有了越來越多的需求,myisam不支持事務,這導致這種存儲引擎很快的落時了。

鎖粒度

並不是說myisam完全不考慮數據安全性,只是它的粒度有些太大了,它為了數據的安全直接動用了表級鎖,直接導致性能影響太大。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一 OpenShift特性 1.1 OpenShift概述 Red Hat OpenShijft Container Platform (OpenShift)是一個容器應用程式平臺,它為開發人員和IT組織提供了一個雲應用程式平臺,用於在安全的、可伸縮的資源上部署新應用程式,而配置和管理開銷最小。 O ...
  • 幾乎所有新手剛接觸 Linux 時,都會被它眾多的發行版本搞得一頭霧水,截至目前,Linux 已經有幾百個發行版本…… 從技術上來說,Linux 只是一個內核,內核指的是一個提供設備驅動、文件系統、進程管理、網路通信等功能的系統軟體,並不是一套完整的操作系統。一些組織或廠商將 Linux 內核與各種 ...
  • linux 解析度設置:找到合適的解析度-cvt 生成解析度參數-添加解析度模式-使用圖形界面選擇; step1:找到合適顯示器的解析度 1366*768 1920*1080 等; step2:打開命令視窗,輸入cvt 1920 1080(假設屏幕合適的解析度為1920*1080) 出現:Model ...
  • CentOS7 源碼部署nginx nginx簡介: nginx是一款高性能的 HTTP 和反向代理 Nginx的優點: 1.高併發量:根據官方給出的數據,能夠支持高達 50,000 個併發連接數的響應 2.記憶體消耗少:處理靜態文件,同樣起web 服務,比apache 占用更少的記憶體及資源,所有它是 ...
  • 在安裝docker時候遇到很多問題,在這裡分享一下, 1.在國內使用docker官方的源真的是慢, https://download.docker.com/linux/centos/#Docker官方源 [root@localhost ~]# cat /etc/yum.repos.d/Docker- ...
  • 通過IP安全策略(以關閉135埠為例) (1) 依次打開“控制面板-->系統和安全-->管理工具-->本地安全策略-->ip安全策略,在本地電腦” (2)在本地組策略編輯器右邊空白處 右鍵單擊滑鼠,選擇“創建IP安全策略”,彈出IP安全策略嚮導對話框,單擊下一步;在出現的對話框中的名稱處寫“名稱 ...
  • Hello 大家好,我是TANZAME,我們又見面了。今天我們來聊聊怎麼手擼一個 Redis Cluster 集群客戶端,純手工有乾貨,您細品。 隨著業務增長,線上環境的QPS暴增,自然而然將當前的單機 Redis 切換到群集模式。燃鵝,我們悲劇地發現,ServiceStack.Redis這個官方推 ...
  • 註意環境變數的設置: 打開終端,輸入: open -e .bash_profile #打開環境變數設置文件 在文件中輸入: export PATH=${PATH}:/usr/local/mysql/bin 保存文件並退出。 安裝完成後,啟動進入的時候會出現這個錯誤: ERROR 1045 (2800 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...