日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Mysql 架构及优化之-索引优化

發布時間:2023/12/31 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mysql 架构及优化之-索引优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

索引基礎知識

索引幫助mysql高效獲取數據的數據結構 索引(mysql中叫"鍵(key)") 數據越大越重要
索引好比一本書,為了找到書中特定的話題,查看目錄,獲得頁碼

select fruit_name from fruit where id = 5 索引列位于id列,索引按值查找并且返回任何包含該值的行
如果索引了多列數據,那么列的順序非常重要


存儲引擎說明

  • myisam 存儲引擎

表鎖:myisam 表級鎖

不支持自動恢復數據:斷電之后 使用之前檢查和執行可能的修復

不支持事務:不保證單個命令會完成, 多行update 有錯誤 只有一些行會被更新

只有索引緩存在內存中:mysiam只緩存進程內部的索引

緊密存儲:行被僅僅保存在一起

  • Innodb存儲引擎

事務性:Innodb支持事務和四種事務隔離級別

外鍵:Innodb唯一支持外鍵的存儲引擎 create table 命令接受外鍵

行級鎖:鎖設定于行一級 有很好的并發性

多版本:多版本并發控制

按照主鍵聚集:索引按照主鍵聚集

所有的索引包含主鍵列:索引按照主鍵引用行 如果不把主鍵維持很短 索引就增長很大

優化的緩存:Innodb把數據和內存緩存到緩沖池 自動構建哈希索引

未壓縮的索引:索引沒有使用前綴壓縮

阻塞auto_increment:Innodb使用表級鎖產生新的auto_increment

沒有緩存的count():myisam 會把行數保存在表中 Innodb中的count()會全表或索引掃描


索引類型

索引在存儲引擎實現的,而不是服務層

  • B-tree 索引

大多數談及的索引類型就是B-tree類型, 可以在create table 和其他命令使用它
myisam使用前綴壓縮以減小索引,Innodb不會壓縮索引 myiam索引按照行存儲物理位置引用被索引的行,Innodb按照主鍵值引用行
B-tree數據存儲是有序的,按照順序保存了索引的列 加速了數據訪問,存儲引擎不會掃描整個表得到需要的數據

  • B-tree 索引實例

create table peple(last_name varchar(50) not null , first_name varchar(50) not null ,dob date not null ,gender enum('m','f') not null ,key(last_name,first_name,dob) #決定索引順序)使用B-tree索引的查詢類型,很好用于全鍵值、鍵值范圍或鍵前綴查找只有在超找使用了索引的最左前綴的時候才有用匹配全名:全鍵值匹配和索引中的所有列匹配查找叫Tang Kang 出生于 1991-09-23 的人 匹配最左前綴:B-tree找到姓為tang的人匹配列前綴: 匹配某列的值的開頭部分 查找姓氏以T開頭的人 匹配范圍值:索引查找姓大于Tang小于zhu的人精確匹配一部分并且匹配某個范圍的另外一部分:查找姓為Tang并且名字以字母K開頭的人 精確匹配last_name列并且對first_name進行范圍查詢只訪問索引的查詢:B-tree支持只訪問索引的查詢,不會訪問行
  • B-tree局限性

B-tree局限性:(案例中索引順序:last_name first_name dob )

如果查找沒有送索引列的最左邊開始,沒有什么用處,即不能查找所有叫Kang 的人 也不能找到所有出生在某天的人,因為這些列不再索引最左邊,也不能使用該索引超找某個姓氏以特定字符結尾的人不能跳過索引的列,即不能找到所有姓氏為Tang并且出生在某個特定日期的人如果不定義first_name列的值,Mysql只能使用索引的第一列存儲引擎不能優化任何在第一個范圍條件右邊的列,比如查詢是where last_name = 'Tang'AND first_name like 'K%' AND dob='1993-09-23' 訪問只能使用索引頭兩列由此可知 索引列順序的重要性!
  • 哈希索引

目前只有Memory存儲引擎支持顯示的哈希索引 而且Memory引擎對我來說不常用所以我們就輕描淡寫的過了吧
  • R-tree(空間索引)

Myisam支持空間索引 可以使用geometry空間數據類型空間索引不會要求where子句使用索引最左前綴可以全方位索引數據可以高效使用任何數據組合查找 配合使用mercontains()函數使用
  • 全文索引

fulltext是Myisam表特殊索引,從文本中找關鍵字不是直接和索引中的值進行比較全文索引可以和B-Tree索引混用 索引價值互不影響全文索引用于match against操作 而不是普通的where子句
  • 前綴索引和索引選擇性

通常索引幾個字符,而不是全部值,以節約空間并得到好的性能 同時也降低選擇性索引選擇性是不重復的索引值和全部行數的比值高選擇性的索引有好處,查找匹配過濾更多的行,唯一索引選擇率為1 最佳狀態blob列 text列 及很長的varchar列 必須定義前綴索引 mysql 不允許索引他們的全文
  • 前綴索引和索引選擇性實例

造數據#復制一份與cs_area表結構mysql> create table area like cs_area ;#插入1600數據mysql> insert into area select * from cs_area limit 1600;#模擬真實數據mysql> update area set name = (select name from cs_area order by rand() limit 1 ); #表area有name列 需要對name列前綴索引

#計算得比值接近0.9350就好了

#分別取 3 4 5位name值計算

#可知name列添加5位前綴索引就可以了

#Mysql不能在order by 或 group by查詢使用前綴索引 也不能將其用作覆蓋索引
  • 聚集索引

聚集索引不是一種單獨的索引類型 而是一種存儲數據的方式Innodb 的聚集索引實際上同樣的結構保存了B-tree索引和數據行"聚集" 是指實際的數據行和相關的鍵值保存在一起 每個表只能有一個聚集索引 因此不能一次把行保存在兩個地方(由于聚集索引對我來說 不常用 我們就略過啦~)
  • 覆蓋索引

索引支持高效查找行 mysql也能使用索引來接收列的數據 這樣不用讀取行數據當發起一個被索引覆蓋的查詢 explain解釋器的extra列看到 using index #滿足條件:## select 查詢的字段必須 有索引全覆蓋select last_name,first_name 其中 last_name 和first_name 必須都有索引#不能在索引執行like操作
  • 為排序使用索引掃描

mysql排序結果的方式:使用文件排序 、 掃描有序的索引explain中的type列若為 "索引(Index)" 說明mysql掃描索引單純掃描索引很快,如果mysql沒有使用索引覆蓋查詢 就不得不查找索引中發現的每一行mysql 能有為排序和查找行使用同樣的索引如表 user 索引 (uid,birthday )使用排序索引:.... where date = '1993-09-23' order by uid desc (索引最左前綴).... where date > '1993-09-23' order by date, uid (兩列索引最左前綴)不能使用索引進行排序的查詢:where date = '1993-09-23' order by uid desc,com_id (使用了不同排序方向,索引都是升序排列)where date = '1993-09-23' order by uid desc,staff_id (引用了不再索引的列)where date = '1993-09-23' order by uid (不能形成最左前綴)where date > '1993-09-23' order by uid,com_id (where有范圍條件 因此不會使用余下索引)
  • 避免多余和重復索引

重復索引:類型相同,以同樣的順序在同樣的列創建索引 比如在表user id列 添加 unique(id)約束 、id not null
primary key 約束 index(id) 其實這些是相同的索引 !

多余索引:如存在(A)索引 應該擴展它 滿足 (A,B)索引
(A,B)索引 <==> (B)
(A,B)索引 <==> (A)
(A,B) A最左前綴 (B,A) B最左前綴

  • 索引實例研究

設計user表 字段:country、 state/region 、city 、sex 、age 、eye 、color
功能:支持組合條件搜索用戶 支持用戶排序 用戶上次在線時間

  • 支持多種過濾條件

不在選擇性很差的列添加索引

  • 優化排序

select name,gender from user where sex='M' order by rating limit 10000,10

即時有索引 (sex,rating) 高偏移量話費很多時間掃描被丟掉的數據

select name,gender from user inner join (select id from user where x.sex = 'M' order by rating limit 100000,10) as x using (id)

基于索引(sex,rating) 提取需要行的主鍵列, 聯接以取得所有需要的列


索引和表維護

表維護三個目標:查找和修復損壞、維護精確的索引統計,并減少碎片

  • 查找并修復表損壞

check table 命令 確定表是否損壞 能抓到大部分表和索引錯誤 repair table 命令修復損壞的表

myisamchk 離線修復工具

  • 更新索引統計

analyze table cs_area 更新索引統計信息 便于優化器優化sql

show index 命令檢查索引的基數性

  • 減少索引和數據碎片

myisam引擎 使用 optimize table 清除碎片 Innodb 引擎 使用 alter table .. engine =
.. 重新創建索引


正則化和非正則化

  • 正則化和非正則化

正則化數據庫:每個因素只會表達一次 教師表teacher (id,school_id) 學校表school
(school_id,school_name) 優點:更新信息只變動一張表 缺點:簡單的學校名稱查詢 需要關聯表
非正則化數據庫:信息是重復的 或者 保存在多個地方

教師表teacher (id,school_id,school_name) 學校表school
(school_id,school_name)

優點:便于直接統計對應學校名稱的老師 缺點:更新需要變動的表多一張

正則化和非正則化并用:比如需要統計用戶的發帖數 可以在user表添加字段num_message 保存發帖總數 避免高密度查詢統計

  • 緩存和匯總表

實例:統計過去24小時發布的信息精確的數量

  • 表周期性創建

周期創建可以得到沒有碎片和全排序索引的高效表

注意此法會將數據清除 只是得到一個沒有碎片和高效的索引表

計數表:比如緩存用戶朋友數量、文件下載次數 通常建立一個單獨的表 以保持快速維護計數器

計劃任務定期聚合函數查詢 更新對應的字段

總結

以上是生活随笔為你收集整理的Mysql 架构及优化之-索引优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。