《大話資料庫》-SQL語句執行時,底層究竟做了什麼小動作?

来源:https://www.cnblogs.com/LiT-26647879-510087153/archive/2020/06/13/13122140.html
-Advertisement-
Play Games

《大話資料庫》-SQL語句執行時,底層究竟做了什麼小動作? 前言 大家好,我是Taoye,試圖用玩世不恭過的態度對待生活的Coder。 現如今我們已然進入了大數據時代,無論是業內還是業外的朋友,相信都有聽說過資料庫這個名詞。數據是一個項目的精華,也扮演著為企業創造價值的重要角色,一個較為完善的公司一 ...


《大話資料庫》-SQL語句執行時,底層究竟做了什麼小動作?

前言

大家好,我是Taoye,試圖用玩世不恭過的態度對待生活的Coder。

現如今我們已然進入了大數據時代,無論是業內還是業外的朋友,相信都有聽說過資料庫這個名詞。數據是一個項目的精華,也扮演著為企業創造價值的重要角色,一個較為完善的公司一般都會有專門的DBA來管理資料庫,以便更好的為用戶服務。

互聯網的發展速度之快,以致大量的APP應用涌入用戶的視野,在大多數APP中都會有“推薦”這一板塊,而這個板塊功能的核心正是基於用戶以往的數據記錄而實現的。再如《死亡筆記》中L·Lawliet這一角色所提到的大數定律,在眾多繁雜的數據中必然存在著某種規律,偶然中必然包含著某種必然的發生。不管是我們提到的大數定律,還是最近火熱的大數據亦或其他領域都離不開大量數據的支持。

如上,我們可初步體會到數據的重要性,而要想更好的管理數據,則避免不了與資料庫打交道。對於資料庫而言,操作資料庫的用戶就相當於一位老闆,我們需要向資料庫發出命令,然後期望資料庫給我們返回想要的結果。

我們可以想象一下這麼一個場景,老闆給Taoye發佈了這麼一個任務:“Taoye啊,你作為一位專業的板磚工,我現在需要你在一小時的之內將工地的轉搬回來。”是的,老闆發佈任務只註重結果和效率,而不在意你板磚的過程。我們在執行SQL語句的時候也是如此,一般只關心執行的結果和效率是否滿足用戶的需求。

最近,Taoye重新把之前學習資料庫時候所記錄的筆記複習了一下,然後又系統性的拜讀了丁奇大大的《MySQL實戰45講》中的內容,所以想要把MySQL系列的知識內容單獨整理出來,在進行自我提高的同時,也希望能給予大家一點幫助。

MySQL的體繫結構

我們要想系統性的學習MySQL資料庫,首先不得不瞭解MySQL的體繫結構。在MySQL中,主要是由什麼功能模塊組成?每一個功能模塊在SQL語句執行的時候分別扮演了一個什麼樣的角色?MySQL的強大之處在哪,竟會受到如此之多的開發者的青睞?這些都是我們每一位學習MySQL的朋友必須瞭解甚至掌握的內容,以下便是MySQL資料庫的體繫結構及其執行流程:

MySQL的體繫結構及執行流程
MySQL的體繫結構及執行流程

從上圖,我們可以看出MySQL整體上主要分為了Server層和存儲引擎層兩個部分。

在Server層內部又包括連接器、緩存、分析器、優化器、執行器等功能部件,主要負責了MySQL的大多數核心服務功能,比如存儲過程、函數、觸發器、視圖等。

而存儲引擎層主要的是負責數據的存儲和提取,在MySQL中可支持MyISAM、InnoDB、Memory等多種存儲引擎,其中最常見的是InnoDB和MyISAM,這也是我們在學習存儲引擎時候的一個重點。在MySQL 5.5.5版本之前預設使用的是MyISAM,而在此版本之後預設採用的是InnoDB存儲引擎。我們在實際創建數據表的時候,也可以通過ENGINE來指定使用的存儲引擎,如下所示。我們可以對tb_comment數據表指定使用MyISAM存儲引擎:

1CREATE TABLE `tb_comment` (
2  `id` int(10unsigned NOT NULL AUTO_INCREMENT,
3  `content` varchar(255DEFAULT NULL,
4  `user_name` varchar(255DEFAULT NULL,
5  `openid` varchar(255DEFAULT NULL,
6  `comment_time` int(11DEFAULT NULL
7  PRIMARY KEY (`id`USING BTREE
8ENGINE=MyISAM AUTO_INCREMENT=175 DEFAULT CHARSET=utf8;

MyISAM和InnoDB這兩種存儲引擎最主要的區別是事務以及鎖機制:

  • InnoDB支持事務,而MyISAM不支持事務
  • InnoDB一般採用的是行鎖,鎖的粒度小,開銷大,鎖表慢,但是在高併發場景下性能更好。而MyISAM採用的是表鎖,特征與行鎖相反。

關於MySQL的事務和鎖機制,這裡只是簡單的提一下,具體的細節我們後面聊。下麵我們將MySQL的體繫結構中每一個功能模塊單獨的分離開來,依次看看每一個功能模塊所體現出的作用。

連接器

我們要想正常的操作資料庫,首先需要經過連接器這道大門。在正式引出連接器之前,各位看官不妨來看看下麵一個例子:

金主大大成天擔心自己財產的安全,必然會將自己的money存儲在銀行金庫中。某一天金主大大要想取出一部分的財產來維持公司的運營,而銀行為了保障金庫中money的安全性,金主必然要進行身份核驗以及一系列防盜系統的檢測。

在MySQL資料庫中,連接器的作用其實就類似於上面的身份校驗以及防盜系統,主要是負責與客戶端建立連接、許可權校驗、維持和管理連接。我們要想操作資料庫,首先需要通過賬號、密碼等信息來連接資料庫,假如我們想要以root賬戶、密碼為666666來連接192.168.31.100:3307的MySQL服務,則可以執行以下命令:

1mysql -h 192.168.31.100 -P 3307 -u root -p 666666
2
3# 如果是本地連接,則執行如下,密碼也可回車後輸入
4mysql -u root -p 666666

當數據匹配成功時,連接器就能允許用戶與資料庫建立連接。此外,連接器還需要驗證該用戶是否有許可權對數據表進行操作,這個時候連接器會去許可權表中查詢連接用戶的許可權,只有在具有操作許可權的前提下才能操作數據表。如果我們在與資料庫已經建立連接的前提下,但是不對資料庫進行任何操作,這個時候連接就會處於空閑狀態,我們可以通過show processlist命令來查看已經建立的連接數和處於空閑狀態的連接,其中command欄位為sleep表示連接空閑:

1mysql> show processlist;
2+----+------+-----------------+------+---------+------+----------+------------------+
3| Id | User | Host            | db   | Command | Time | State    | Info             |
4+----+------+-----------------+------+---------+------+----------+------------------+
5|
  3 | root | localhost:53372 | NULL | Sleep   |   28 |          | NULL             |
6|  4 | root | localhost:53378 | NULL | Query   |    0 | starting | show processlist |
7+----+------+-----------------+------+---------+------+----------+------------------+
8

如果連接長期處於空閑狀態而不做任何操作,當超過一定時間時,就會自動斷開連接,而這個時間閾值主要是通過wait_timeout屬性來決定的,預設是28800,即8小時。show variables like '%wait_timeout%'"可查看時間閾值,set @@session.wait_timeout=xxx可修改當前會話下的時間閾值,具體操作如下:

 1mysql> set @@session.wait_timeout=30000;
2Query OK, 0 rows affected (0.00 sec)
3
4mysql> show variables like "%wait_timeout%";
5+--------------------------+----------+
6| Variable_name            | Value    |
7+--------------------------+----------+
8|
 innodb_lock_wait_timeout | 50       |
9| lock_wait_timeout        | 31536000 |
10|
 wait_timeout             | 30000    |
11+--------------------------+----------+
123 rows in set, 1 warning (0.00 sec)

緩存

緩存這個概念,學習過《電腦組成原理》或是其他相關課程的朋友應該並不陌生,緩存一般使用的是SRAM(靜態隨機存儲器)技術實現的,相較於DRAM(動態隨機存儲器)而言,它最主要的優勢在於速度快,能夠大大提高數據的查詢效率。

關於緩存,我們可以來做一個簡答的計算題:
假設查詢一次緩存需要1s,查詢一次記憶體需要10s,緩存命中的概率為90%,一位用戶想要查詢100次,則使用緩存和不使用緩存的平均查詢時間是多少?

可見,根據局部性原理,緩存的存在是可以大大提高數據的查詢效率的。

由上方的執行流程圖,我們也可以知道,客戶端通過連接器與MySQL伺服器建立連接之後,這個時候就會來到緩存中查詢用戶所需的數據。假設用戶向MySQL發出以下一條查詢語句:

1mysql> select * from tb_comment where id=1;

MySQL收到用戶發出的請求之後,就會先到緩存中看看之前是否有執行過相同的語句,而且之前執行的結果會以key-value鍵值對的形式直接進行存儲。假如之前有執行過這條命令,則直接從緩存中取出數據並反饋給用戶,如果沒有執行過,則會繼續走 分析器 -> 優化器 -> 執行器 -> 存儲引擎這條鏈路。所以說,緩存的命中可以省去後面一系列操作所消耗的時間,這也是緩存提高查詢效率的原因。

按道理來講,緩存的引入應該是相當不錯的,而且用戶查詢次數越多就越能體現緩存的強大,但為什麼在MySQL 8.0版本之後直接捨去了緩存部件呢?

在理想情況下,緩存引入確實是非常的完美,但是在資料庫中,我們除了查詢操作之外,還有更新操作(增、刪、改)。每當我們執行過一次更新操作的時候,資料庫中的數據就已然發生了改變,而當我們再次發出命令從緩存中取出的數據就不再是用戶所期望的數據了。所以對MySQL而言,每當用戶進行更新操作時,都會清空一次緩存,然後再次重新緩存新的數據,而這個過程給MySQL帶來的壓力是很大的,也大大削弱了SQL語句的執行效率。所以說,緩存對於一些查詢多,更新少的數據表比較有用,而對那些更新比較頻繁的數據表就會適得其反。

如果使用的是MySQL 8.0以下的版本,我們可以根據實際需求來確定是否開啟緩存,主要是通過my.cnf配置文件中的query_cache_type來決定的,0代表禁用緩存,1

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

-Advertisement-
Play Games
更多相關文章
  • linux 用戶 1、用戶相關 1.1useradd useradd 選項 用戶名 1.2passwd passwd 選項 用戶名 1.3 例子: 1.3.1創建用戶testuser 主目錄為home/testuser useradd –d /home/testuser -m testuser 1. ...
  • 最近開始接觸websocket,第一次裝的時候,還是遇到了些問題,這裡記錄一下 1.從git下載uWebSockets 地址:https://github.com/uNetworking/uWebSockets git clone https://github.com/uNetworking/uWe ...
  • Linux基礎知識、Shell編程、Linux系統管理、Linux服務管理、MySQL資料庫管理、Linux集群、Linux虛擬化 ...
  • 本文主要闡述了UNIX與Linux發展史、開源軟體簡介、Linux應用領域 ...
  • 單行編輯控制項具有ES_密碼樣式。預設情況下,具有此樣式的編輯控制項為用戶鍵入的每個字元顯示一個星號。 但是,本例使用EM_SETPASSWORDCHAR消息將預設字元從星號更改為加號(+)。以下屏幕截圖顯示用戶輸入密碼後的對話框。 步驟1:創建密碼對話框的實例。 下麵的C++代碼示例使用DealBox ...
  • 最近安裝了datagrip操作達夢資料庫,發現有一個問題:dagagrip無法獲取dbms_output的輸出,在oracle是可以的,但在達夢不行。 於是聯想到一個問題:c語言裡面怎麼獲取dbms_output的輸出? 百度了一下,沒有找到明確的答案,但是找到了jdbc獲取dbms_output輸 ...
  • 安裝達夢windows版資料庫時,會附帶安裝一個資料庫管理工具。這個工具是我知道的,最全面的達夢資料庫可視化數據操作工具。、 除了支持常規的dml操作外,還支持存儲過程開發與調試,同時提供了簡單的操作歷史記錄查詢,sql自動補全,資料庫對象管理等功能。 但用慣了oracle的人,可能還是會更習慣PL ...
  • 文章開始啰嗦兩句,寫到這裡共21篇關於redis的瑣碎知識,沒有過多的寫編程過程中redis的應用,著重寫的是redis命令、客戶端、伺服器以及生產環境搭建用到的主從、哨兵、集群實現原理,如果你真的能看的進去,相信對你在以後用到redis時會有一定的幫助。 寫到現在,redis相關的內容暫時告一段落 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...