MySQL-七種SQL優化

一、插入數據

普通插入:

  1. 采用批量插入(一次插入的數據不建議超過1000條)
insert into tb_test values(1,'Tom'),(3, 'Cat'),(3, 'Jerry')....
  1. 手動提交事務
start transaction;
insert into tb_test values(1,'Tom'),(3, 'Cat'),(3, 'Jerry');
insert into tb_test values(4,'Tom'),(5, 'Cat'),(6, 'Jerry');
insert into tb_test values(7,'Tom'),(8, 'Cat'),(9, 'Jerry');
commit;
  1. 主鍵順序插入性能高于亂序插入

大批量插入:

如果一次性需要插入大批量數據,使用insert語句插入性能較低,此時可以使用MySQL數據庫提供的load指令插入。

# 客戶端連接服務端時,加上參數 --local-infile
mysql --local-infile -u root -p
# 查看全局參數local_infile是否開啟
select @@local_infile;
# 設置全局參數local_infile為1,開啟從本地加載文件導入數據的開關
set global local_infile = 1;
# 執行load指令將準備好的數據,加載到表結構中
# 將sql100w.sql文件的數據加載到tb_user表中
# 用逗號分隔字段
load data local infile '/root/sql100w.sql' into table 'tb_user' fields terminated by ',' lines terminated by '\n';

二、主鍵優化

數據組織方式:在InnoDB存儲引擎中,表數據都是根據主鍵順序組織存放的,這種存儲方式的表稱為索引組織表(Index organized table, IOT)

  • 頁分裂:頁可以為空,也可以填充一般,也可以填充100%,每個頁包含了2-N行數據(如果一行數據過大,會行溢出),根據主鍵排列。
  • 頁合并:當刪除一行記錄時,實際上記錄并沒有被物理刪除,只是記錄被標記(flaged)為刪除并且它的空間變得允許被其他記錄聲明使用。當頁中刪除的記錄到達MERGE_THRESHOLD(默認為頁的50%),InnoDB會開始尋找最靠近的頁(前后)看看是否可以將這兩個頁合并以優化空間使用。

MERGE_THRESHOLD:合并頁的閾值,可以自己設置,在創建表或創建索引時指定。

主鍵設計原則:

  • 滿足業務需求的情況下,盡量降低主鍵的長度。
  • 插入數據時,盡量選擇順序插入,選擇使用 AUTO_INCREMENT 自增主鍵。
  • 盡量不要使用 UUID 做主鍵或者是其他的自然主鍵,如身份證號。
  • 業務操作時,避免對主鍵的修改。

三、order by優化

在MySQL中排序分為以下兩種清空:

  1. Using filesort:通過表的索引或全表掃描,讀取滿足條件的數據行,然后在排序緩沖區 sort buffer 中完成排序操作,所有不是通過索引直接返回排序結果的排序都叫 FileSort 排序。
  2. Using index:通過有序索引順序掃描直接返回有序數據,這種情況即為 using index,不需要額外排序,操作效率高。
#創建索引,兩個字段,全部降序或全部升序會走這個索引
create index idx_user_age_phone+aa on tb_user(age,phone);#創建索引,一個升,一個降
create index idx_user_age_phone_ad on tb_user(age asc, phone desc);

總結:

  • 根據排序字段建立合適的索引,多字段排序時,也遵循最左前綴法則。
  • 盡量使用覆蓋索引,少使用select *
  • 多字段排序,一個升序一個降序,此時需要注意聯合索引在創建時的規則(ASC/DESC)。
  • 如果不可避免出現filesort,大數據量排序時,可以適當增大排序緩沖區大小 sort_buffer_size(默認256k)。

注: 在創建多列索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。

四、group by優化

  • 在分組操作時,可以通過索引來提高效率。
  • 分組操作時,索引的使用也是滿足最左前綴法則的。

如索引為idx_user_pro_age_stat,則句式可以是select ... where profession order by age,這樣也符合最左前綴法則。

五、limit優化

常見的問題:limit 2000000,10,此時需要 MySQL 排序前2000000條記錄,但僅僅返回2000000 - 2000010的記錄,其他記錄丟棄,查詢排序的代價非常大。
優化方案:一般分頁查詢時,通過創建覆蓋索引能夠比較好地提高性能,可以通過覆蓋索引加子查詢形式進行優化。

例如:

# 此語句耗時很長
select * from tb_sku limit 9000000, 10;
# 通過覆蓋索引加快速度,直接通過主鍵索引進行排序及查詢出id
select id from tb_sku order by id limit 9000000, 10;
# 通過子查詢查出所有字段
select * from tb_sku as s, (select id from tb_sku order by id limit 9000000, 10) as a where s.id = a.id;

六、count優化

select count(*) from tb_user;
  • MyISAM 引擎把一個表的總行數存在了磁盤上,因此執行 count(*) 的時候會直接返回這個數,效率很高。
  • InnoDB 引擎在執行 count(*) 時,需要把數據一行一行地從引擎里面讀出來,然后累計計數。
  • 優化方案:自己計數,如創建key-value表存儲在內存或硬盤,或者是用redis。

count的幾種用法:

  • 如果count函數的參數(count里面寫的那個字段)不是NULL(字段值不為NULL),累計值就加一,最后返回累計值。
  • 用法:count(*)、count(主鍵)、count(字段)、count(1)。
  • count(主鍵)跟count(*)一樣,因為主鍵不能為空;
  • count(字段)只計算字段值不為NULL的行;
  • count(1)引擎會為每行添加一個1,然后就count這個1,返回結果也跟count(*)一樣;
  • count(null)返回0。

各種用法的性能:

  • count(主鍵):InnoDB引擎會遍歷整張表,把每行的主鍵id值都取出來,返回給服務層,服務層拿到主鍵后,直接按行進行累加(主鍵不可能為空)。
  • count(字段):沒有not null約束的話,InnoDB引擎會遍歷整張表把每一行的字段值都取出來,返回給服務層,服務層判斷是否為null,不為null,計數累加;有not null約束的話,InnoDB引擎會遍歷整張表把每一行的字段值都取出來,返回給服務層,直接按行進行累加。
  • count(1):InnoDB 引擎遍歷整張表,但不取值。服務層對于返回的每一層,放一個數字 1 進去,直接按行進行累加。
  • count(*):InnoDB 引擎并不會把全部字段取出來,而是專門做了優化,不取值,服務層直接按行進行累加。

按效率排序:count(字段) < count(主鍵) < count(1) < count(*),所以盡量使用 count(*)

七、update優化(避免行鎖升級為表鎖)

InnoDB 的行鎖是針對索引加的鎖,不是針對記錄加的鎖,并且該索引不能失效,否則會從行鎖升級為表鎖。

例如:
update student set no = '1' where id = 1; 這句由于id有主鍵索引,所以只會鎖這一行;
update student set no = '1' where name = 'zheng'; 這句由于name沒有索引,所以會把整張表都鎖住進行數據更新,解決方法是給name字段添加索引;

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

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

相關文章

LeetCode 2878.獲取DataFrame的大小

DataFrame players: ------------------- | Column Name | Type | ------------------- | player_id | int | | name | object | | age | int | | position | object | | … | … | ------------------- 編寫一個解決方案&#xff0c;計算并顯示 players 的 行數和列數。 將結…

maven插件wagon-ssh、os-maven-plugin、buildnumber-maven-plugin使用詳解

文章目錄 前言一、os-maven-plugin的使用二、buildnumber-maven-plugin使用1、時間戳策略2、數字策略 三、wagon-ssh使用1、上傳文件/文件夾2、執行Linux命令或者shell腳本 總結 前言 有時我們在構建項目時&#xff0c;希望能自動生成版本號或者生成不同操作系統標識的版本后綴…

Java實戰:Spring Boot實現郵件發送服務

本文將詳細介紹如何在Spring Boot應用程序中實現郵件發送服務。我們將探討Spring Boot集成郵件發送服務的基本概念&#xff0c;以及如何使用Spring Boot和第三方郵件服務提供商來實現郵件發送。此外&#xff0c;我們將通過具體的示例來展示如何在Spring Boot中配置和使用郵件發…

RS?FSVA3000 信號與頻譜分析儀

R&SFSVA3000 信號與頻譜分析儀 非常適用于實驗室以及生產過程中的高要求信號分析任務。R&SFSVA3000 信號與頻譜分析儀的分析帶寬高達 1 GHz&#xff0c;并具有低至 –120 dBc/Hz 的相位噪聲和高動態范圍&#xff0c;適用于要求嚴格的 5G NR 測量應用。分析儀測量速度快…

代碼隨想錄算法訓練營第二天

● 今日學習的文章鏈接和視頻鏈接 ● 自己看到題目的第一想法 977.有序數組的平方 方法一&#xff1a; 思路&#xff1a; 先將數據所有數據平方將數組排序 代碼&#xff1a; class Solution { public:vector<int> sortedSquares(vector<int>& nums) {vect…

vue后臺管理添加水印簡單方式watermark-package

詳情參考:https://www.npmjs.com/package/watermark-package 示例方法 <el-button type"primary" click"AddWatermark">添加水印</el-button><el-button type"primary" click"RemoveWatermark">清除水印</el-but…

Linux調試器——gdb的基礎使用

目錄 1.背景 2.指令的使用 2.1gdb的使用和退出 2.2顯示源代碼 2.3運行程序 2.4調試 1.打斷點 2.查斷點 3.去斷點 4.運行 5.關閉斷點 6.啟用斷點 7.逐過程 8.進入函數 9.顯示變量的值 1.背景 眾所周知&#xff0c;我們的程序發布有兩種&#xff0c;分別是debug模式和release模式…

18.貪心算法

排序貪心 區間貪心 刪數貪心 統計二進制下有多少1 int Getbit_1(int n){int cnt0;while(n){nn&(n-1);cnt;}return cnt; }暴力加一維前綴和優化 #include <iostream> #include <climits> using namespace std; #define int long long const int N2e510; in…

uni-app 經驗分享,從入門到離職(五)——由淺入深 uni-app 數據緩存

文章目錄 &#x1f4cb;前言?關于專欄 &#x1f3af;什么是數據存儲&#x1f9e9;數據存儲——存儲&#x1f4cc; uni.setStorage(OBJECT)&#x1f4cc; uni.setStorageSync(KEY,DATA) &#x1f9e9;數據存儲——獲取&#x1f4cc; uni.getStorage(OBJECT)&#x1f4cc; uni.g…

2024年【起重機司機(限橋式起重機)】找解析及起重機司機(限橋式起重機)考試總結

題庫來源&#xff1a;安全生產模擬考試一點通公眾號小程序 2024年【起重機司機(限橋式起重機)】找解析及起重機司機(限橋式起重機)考試總結&#xff0c;包含起重機司機(限橋式起重機)找解析答案和解析及起重機司機(限橋式起重機)考試總結練習。安全生產模擬考試一點通結合國家…

[AI]部署安裝有道QanyThing

前提條件&#xff1a; 1、win10系統更新到最新的版本&#xff0c;系統版本最好為專業版本 winver 查看系統版本&#xff0c;內部版本要大于19045 2、CPU開啟虛擬化 3、開啟虛擬化功能&#xff0c;1、2、3每步完成后均需要重啟電腦&#xff1b; 注&#xff1a;windows 虛擬…

CSS輕松學:簡單易懂的CSS基礎指南

css基礎 更多web開發知識歡迎訪問我的專欄>>> 01-CSS初體驗 層疊樣式表 (Cascading Style Sheets&#xff0c;縮寫為 CSS&#xff09;&#xff0c;是一種 樣式表 語言&#xff0c;用來描述 HTML 文檔的呈現&#xff08;美化內容&#xff09;。 書寫位置&#xff1a;…

基于HAL庫的STM32-ADC學習(附帶代碼)

1.前言 STM32ADC是一種模擬/數字轉換器&#xff0c;可以將模擬信號轉換為數字信號。STM32ADC有多個通道&#xff0c;可以選擇不同的輸入源、轉換模式、觸發方式和采樣時間。STM32ADC的轉換結果可以通過中斷、DMA或者寄存器讀取。 在本文中&#xff0c;我將介紹如何使用STM32C…

第九屆大數據與計算國際會議 (ICBDC 2024) 即將召開!

2024年第九屆大數據與計算國際會議&#xff08;ICBDC 2024&#xff09;將于2024年5月24至26日在泰國曼谷舉行。本次會議由朱拉隆功大學工程學院工業工程系主辦。ICBDC 2024的宗旨是展示大數據和計算主題相關科學家的最新研究和成果&#xff0c;為來自不同地區的專家代表們提供一…

嵌入式學習筆記總結Day23----minshell項目總結

今天進行了linux系統高級編程io階段學習的結尾&#xff0c;完成了一個minshell的小項目。 一、項目介紹 利用Linux中IO接口實現MiniShell&#xff0c;實現常用的shell指令的實現。 項目想要實現需要思考的地方有&#xff1a; 1.如何打印終端命令 2.如何接受終端命令 3.實現對…

Sora - 探索AI視頻模型的無限可能-官方報告解讀與思考

一、引言 最近SORA火爆刷屏&#xff0c;我也忍不住找來官方報告分析了一下&#xff0c;本文將深入探討OpenAI最新發布的Sora模型。Sora模型不僅僅是一個視頻生成器&#xff0c;它代表了一種全新的數據驅動物理引擎&#xff0c;能夠在虛擬世界中模擬現實世界的復雜現象。本文將重…

[力扣 Hot100]Day33 排序鏈表

題目描述 給你鏈表的頭結點 head &#xff0c;請將其按 升序 排列并返回 排序后的鏈表 。 出處 思路 歸并排序即可。 代碼 class Solution { public:ListNode* merge(ListNode *h1,ListNode *h2) {ListNode *head nullptr;if(h1->val<h2->val){head h1;h1h1-…

2024.2.22 C++QT 作業

思維導圖 練習題 1>完善對話框&#xff0c;點擊登錄對話框&#xff0c;如果賬號和密碼匹配&#xff0c;則彈出信息對話框&#xff0c;給出提示”登錄成功“&#xff0c;提供一個Ok按鈕&#xff0c;用戶點擊Ok后&#xff0c;關閉登錄界面&#xff0c;跳轉到其他界面。如果賬…

Stream、Collections、Collectors用法

當涉及Java編程中的集合處理時&#xff0c;Stream、Collections和Collectors是三個常用的工具。以下是它們各自的主要功能和使用的一些方法的概要&#xff1a; Stream&#xff1a; 概要&#xff1a;Stream 是 Java 8 引入的一個強大工具&#xff0c;用于處理集合數據的流式操作…

Vue響應式狀態ref()與reactive()

1. ref()聲明響應式狀態 <template><!--在DOM元素調用變量時,不需要指定輸出變量的value,因為Vue會幫你輸出.value但是注意,這個幫助只會幫助頂級的ref屬性才會被解包--><div>{{ count }}</div><div>{{ object }}</div><div>{{ arr…