SQL優化

一、插入數據 優化

1.1? 普通插入(小數據量)

普通插入(小數據量):

  1. 采用批量插入(一次插入的數據不建議超過1000條)
  2. 手動提交事務
  3. 主鍵順序插入

?1.2? 大批量數據插入

?大批量插入:(主鍵順序插入的性能高于亂序插入)
如果一次性需要插入大批量數據,使用insert語句插入性能較低,此時可以使用MySQL數據庫提供的load指令插入。

  1. # 客戶端連接服務端時,加上參數 --local-infile(這一行在bash/cmd界面輸入)
  2. mysql --local-infile -u root -p
  3. # 設置全局參數local_infile為1,開啟從本地加載文件導入數據的開關
  4. set global local_infile = 1;
  5. select @@local_infile;? ?#查重參數
  6. # 執行load指令將準備好的數據,加載到表結構中
  7. load data local infile '/root/sql1.log' into table 'tb_user' fields terminated by ',' lines terminated by '\n';

案例具體解釋如下:

  • '/root/sql1.log':表示要加載的文件路徑,這里假設文件位于根目錄下的sql1.log文件。
  • 'tb_user':表示要將數據加載到的目標表的名稱為'tb_user'。
  • FIELDS TERMINATED BY ',':表示文件中的字段是由逗號進行分隔的。
  • LINES TERMINATED BY '\n':表示文件中的行是以換行符(\n)結束的。

二、主鍵優化

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

由于“表數據都是根據主鍵順序組織存放的”,所以順序插入的效率高。

主鍵設計原則:

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

三、order by 優化

  1. Using filesort:通過表的索引或全表掃描,讀取滿足條件的數據行,然后在排序緩沖區 sort buffer 中完成排序操作,所有不是通過索引直接返回排序結果的排序都叫 FileSort 排序
  2. Using index:通過有序索引順序掃描直接返回有序數據,這種情況即為 using index,不需要額外排序,操作效率高

如果order by字段全部使用升序排序或者降序排序,則都會走索引,但是如果一個字段升序排序,另一個字段降序排序,則不會走索引,explain的extra信息顯示的是Using index, Using filesort,如果要優化掉Using filesort,則需要另外再創建一個索引,如:create index idx_user_age_phone_ad on tb_user(age asc, phone desc);,此時使用select id, age, phone from tb_user order by age asc, phone desc;會全部走索引?

總結:

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

四、group by 優化

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

如索引為idx_user_pro_age_stat,則句式可以是select ... where profession order by age,這樣也符合最左前綴法則。索引 idx_user_pro_age_stat 所包含的列順序是 profession, age, stat。查詢的條件是 WHERE profession,而排序的條件是 ORDER BY age。由于 profession 列出現在了索引的最左邊,并且查詢和排序都是從最左邊的列開始的,所以這個查詢語句可以利用該索引進行優化。

五、limit 優化

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

案例:

  1. -- 此語句耗時很長
  2. select * from tb_sku limit 9000000, 10;
  3. -- 通過覆蓋索引加快速度,直接通過主鍵索引進行排序及查詢
  4. select id from tb_sku order by id limit 9000000, 10;
  5. -- 下面的語句是錯誤的,因為 MySQL 不支持 in 里面使用 limit
  6. -- select * from tb_sku where id in (select id from tb_sku order by id limit 9000000, 10);
  7. -- 通過連表查詢即可實現第一句的效果,并且能達到第二句的速度
  8. select * from tb_sku as s, (select id from tb_sku order by id limit 9000000, 10) as a where s.id = a.id;

在一般的分頁查詢中,需要獲取指定頁碼的數據行。傳統的做法是通過LIMIT語句來限制返回結果的行數,但這可能需要進行全表掃描,并且只有在獲取完整結果集后才會進行截取,效率較低。

通過創建覆蓋索引,可以避免對主表的訪問,直接從索引中獲取所需的列數據,提高查詢速度。覆蓋索引是一種包含所有查詢需要的列的索引。當查詢只需要返回覆蓋索引中的列時,不需要再回到主表查找相應的行,從而節省了IO操作。

此外,使用子查詢形式可以進一步優化分頁查詢。子查詢是將一個查詢嵌套在另一個查詢中的查詢方式。在分頁查詢中,可以先執行一個子查詢來獲取滿足條件的主鍵或唯一標識符,并將其作為條件用于主查詢,以獲取特定的頁碼數據。

六、count 優化

MyISAM 引擎把一個表的總行數存在了磁盤上,因此執行 count(*) 的時候會直接返回這個數,效率很高(前提是不適用where);
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(1) >count(主鍵) >= count(字段),所以盡量使用 count(*)?

七、updata 優化

當使用UPDATE語句更新數據時,如果WHERE條件選擇的是不帶索引的字段,可能導致行鎖升級為表鎖。這是因為在沒有索引的情況下,數據庫無法快速定位到需要更新的行,只能對整個表或較大的數據范圍進行鎖定,以確保數據的一致性。

WHERE條件選擇帶索引的字段時,數據庫可以利用索引來快速定位到滿足條件的行,只對特定的行進行鎖定,從而減少鎖沖突和提高并發性能。這樣可以避免行鎖升級為表鎖,并減少對其他事務的影響。

?

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

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

相關文章

Android 開發中需要了解的 Gradle 知識

作者:wkxjc Gradle 是一個基于 Groovy 的構建工具,用于構建 Android 應用程序。在 Android 開發中,了解 Gradle 是非常重要的,因為它是 Android Studio 默認的構建工具,可以幫助我們管理依賴項、構建應用程序、運行測試…

macOS 如何安裝git和nvm

首先:先來安裝git 打開macOS終端 將下面的命令復制粘貼進去: curl -O https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.41.0.tar.gz 版本號可以參考一下官網的 我這里安裝的是目前最新的2.41.0 然后在終端輸入下面的代碼或者雙擊git的…

數據結構:力扣OJ題

目錄 ?編輯題一:鏈表分割 思路一: 題二:相交鏈表 思路一: 題三:環形鏈表 思路一: 題四:鏈表的回文結構 思路一: 鏈表反轉: 查找中間節點: 本人實力…

YOLOv8+ByteTrack多目標跟蹤(行人車輛計數與越界識別)

課程鏈接:https://edu.csdn.net/course/detail/38901 ByteTrack是發表于2022年的ECCV國際會議的先進的多目標跟蹤算法。YOLOv8代碼中已集成了ByteTrack。本課程使用YOLOv8和ByteTrack對視頻中的行人、車輛做多目標跟蹤計數與越界識別,開展YOLOv8目標檢測…

Leetcode每日一題:23. 合并 K 個升序鏈表(2023.8.12 C++)

目錄 23. 合并 K 個升序鏈表 題目描述: 實現代碼與解析: 優先級隊列: 原理思路: 23. 合并 K 個升序鏈表 題目描述: 給你一個鏈表數組,每個鏈表都已經按升序排列。 請你將所有鏈表合并到一個升序鏈表…

Flutter: A RenderFlex overflowed by 42 pixels on the bottom.

Flutter:渲染活動底部上方溢出了42個像素 Flutter 控件超出異常:A RenderFlex overflowed by 42 pixels on the bottom. 解決方案 1.Scaffold內添加 resizeToAvoidBottomInset 屬性,缺點是軟鍵盤下面的控件被擋住 Scaffold( resizeToAvoidBot…

第一百二十七天學習記錄:我的創作紀念日

機緣 今天收到CSDN官方的來信,想想也可以對我前面的學習記錄進行一個總結。 關于來到CSDN的初心,也就是為了讓自己養成一個良好的學習總結的習慣。這里要感謝我C語言視頻教程的老師,是他建議學生們在技術博客中進行記錄。對于技術博客&…

web-Element

在vueapp里<div><!-- <h1>{{message}}</h1> --><element-view></element-view></div> <div><!-- <h1>{{message}}</h1> --><element-view></element-view></div>在view新建個文件 <t…

C++ VTK 8.2 如何繪制彈簧圖形

//創建圓柱 vtkSmartPointer<vtkCylinderSource> spCylinderSource vtkSmartPointer<vtkCylinderSource>::New(); spCylinderSource->SetHeight(m_dCylinderHeight); // 設置圓柱的高度 spCylinderSource->SetRadius(m_dCylinderRadius)…

Spring(12) BeanFactory 和 ApplicationContext 區別

目錄 一、BeanFactory 和 ApplicationContext 區別&#xff1f;二、既然 Spring Boot 中使用的是 ApplicationContext 進行應用程序的啟動和管理&#xff0c;那么 Spring Boot 會用到 BeanFactory 嗎&#xff1f; 一、BeanFactory 和 ApplicationContext 區別&#xff1f; Bea…

git clone使用https協議報錯OpenSSL SSL_read: Connection was reset, errno 10054

在使用git 下載github上的代碼時&#xff0c; 一般有ssh協議和https協議兩種。使用ssh協議可以成功clone代碼&#xff0c; 但使用https協議時出錯&#xff1a; $ git clone https://github.com/openai/improved-diffusion.git Cloning into improved-diffusion... fatal: unab…

vue或uniapp使用pdf.js預覽

一、先下載穩定版的pdf.js&#xff0c;可以去官網下載 官網下載地址 或 pdf.js包下載(已配置好&#xff0c;無需修改) 二、下載好的pdf.js文件放在public下靜態文件里&#xff0c; uniapp是放在 static下靜態文件里 三、使用方式 1. vue項目 注意路徑 :src"static/pd…

每日一題 206反轉鏈表

題目 給你單鏈表的頭節點 head &#xff0c;請你反轉鏈表&#xff0c;并返回反轉后的鏈表。 示例 1&#xff1a; 輸入&#xff1a;head [1,2,3,4,5] 輸出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 輸入&#xff1a;head [1,2] 輸出&#xff1a;[2,1]示例 3&#xff1a; …

塊、行內塊水平垂直居中

1.定位實現水平垂直居中 <div class"outer"><div class"test inner1">定位實現水平垂直居中</div></div><style>.outer {width: 300px;height: 300px;border: 1px solid gray;margin: 100px auto 0;position: relative;}.te…

途樂證券-新股行情持續火爆,哪些因素影響首日表現?

全面注冊制以來&#xff0c;參加打新的投資者數量全體呈現下降。打新收益下降&#xff0c;破發頻出的布景下&#xff0c;投資者打新策略從逢新必打逐步向優選個股改變。 經過很多歷史數據&#xff0c;從商場定價、參加者熱度以及機構重視度維度揭秘了上市后股價體現優秀的個股具…

在多頁面應用和單頁面應用中(例如vue)怎么提高seo搜索引擎優化

那么 我們要先知道 搜索引擎是怎么工作的&#xff1f; 搜索引擎是通過一系列步驟來工作的&#xff0c;以下是其基本原理&#xff1a; 1、網絡爬蟲&#xff1a;搜索引擎使用網絡爬蟲&#xff08;也稱為蜘蛛、機器人&#xff09;來從互聯網上抓取網頁。網絡爬蟲按照預定義的規則…

Redis 之 緩存預熱 緩存雪崩 緩存擊穿 緩存穿透

目錄 一、緩存預熱 1.1 緩存預熱是什么&#xff1f; 1.2 解決方案&#xff1a; 二、緩存雪崩 2.1 緩存雪崩是什么&#xff1f;怎么發生的&#xff1f; 2.2 怎么解決 三、緩存穿透 3.1 是什么&#xff1f;怎么產生的呢&#xff1f; 3.2 解決方案 3.2.1、采用回寫增強&a…

Ceph入門到精通-分布式存儲產品的測試實踐

分布式存儲產品的測試實踐 在分布式存儲產品的測試過程中&#xff0c;測試到底做了些什么事情呢&#xff1f; 一&#xff1a;測試工作內容 需求&#xff0c;設計評審 測試需要參與到每一個過程中 在設計評審的時候就需要知道驗收的標準&#xff0c;這是最重要的開始。因為這…

SpringBoot基礎之注冊Servlet三大組件

文章目錄 前言一、介紹二、注入Bean2.1.ServletRegistrationBean2.2.FilterRegistrationBean2.3.ServletListenerRegistrationBean 三.演示結果總結 前言 本文章將介紹SpringBoot注冊Servlet的三大組件 一、介紹 由于SpringBoot默認是以jar包的方式運行嵌入式Servlet容器來啟…

Protues如何安裝下載使用:STM32利用Protues進行仿真

文章目錄&#xff1a; 一&#xff1a;Proteus仿真的使用步驟 第一步&#xff1a;Proteus新建項目 第二步&#xff1a;Proteus設計電路圖&#xff08;選取元器件、擺放元器件、編輯元器件屬性、原理圖布線&#xff09; 第三步&#xff1a;程序代碼編寫 第四步&#xff1a;…