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

歡迎訪問 生活随笔!

生活随笔

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

数据库

mysql范围条件_MySQL 索引及优化实战(一)

發布時間:2025/3/21 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql范围条件_MySQL 索引及优化实战(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

mysql

隨著系統用戶量的不斷增加,MySQL 索引的重要性不言而喻,對于后端工程師,只有在了解索引及其優化的規則,并應用于實際工作中后,才能不斷的提升系統性能,開發出高性能、高并發和高可用的系統。

MySQL 索引及優化實戰(一)和(二)會跟大家介紹一下 MySQL 索引中的各種概念,然后介紹優化索引的若干條規則,最后利用這些規則,針對面試中常考的知識點,做詳細的實例分析。通過這兩篇文章,您將學到如下內容:

1. MySQL 索引概念:聚集索引、非聚集索引、聯合索引、主鍵、外鍵、唯一索引等。

2. MySQL 索引優化規則:前導模糊查詢、or / in / union、負向查詢、null、最左前綴等。

3. 常見面試題分析:通過大量實例來說明如何優化索引。

索引概念和作用

索引是一種使記錄有序化的技術,它可以指定按某列/某幾列預先排序,從而大大提高查詢速度(類似于漢語詞典中按照拼音或者筆畫查找)。

索引的主要作用是加快數據查找速度,提高數據庫的性能。

MySQL 索引類型

從物理存儲角度上,索引可以分為聚集索引和非聚集索引。

1.聚集索引(Clustered Index)

聚集索引決定數據在磁盤上的物理排序,一個表只能有一個聚集索引。

2.非聚集索引(Non-clustered Index)

非聚集索引并不決定數據在磁盤上的物理排序,索引上只包含被建立索引的數據,以及一個行定位符 row-locator,這個行定位符,可以理解為一個聚集索引物理排序的指針,通過這個指針,可以找到行數據。

從邏輯角度,索引可以分為以下幾種。

1. 普通索引

最基本的索引,它沒有任何限制。

2. 唯一索引

與普通索引類似,不同的就是索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。

3. 主鍵索引

它是一種特殊的唯一索引,用于唯一標識數據表中的某一條記錄,不允許有空值,一般用 primary key 來約束。主鍵和聚集索引的關系詳見“問題詳解”中的第4題。

4. 聯合索引(又叫復合索引)

多個字段上建立的索引,能夠加速復合查詢條件的檢索。

5. 全文索引

老版本 MySQL 自帶的全文索引只能用于數據庫引擎為 MyISAM 的數據表,新版本 MySQL 5.6 的 InnoDB 支持全文索引。默認 MySQL 不支持中文全文檢索,可以通過擴展 MySQL,添加中文全文檢索或為中文內容表提供一個對應的英文索引表的方式來支持中文。

MySQL索引優化規則

可以通過以下規則對 MySQL 索引進行優化。

1. 前導模糊查詢不能使用索引。

例如下面 SQL 語句不能使用索引。

select * from doc where title like '%XX'

而非前導模糊查詢則可以使用索引,如下面的 SQL 語句。

select * from doc where title like 'XX%'

頁面搜索嚴禁左模糊或者全模糊,如果需要可以用搜索引擎來解決。

2. union、in、or 都能夠命中索引,建議使用 in。

1)union:能夠命中索引。

示例代碼如下:

select * from doc where status=1union allselect * from doc where status=2

直接告訴 MySQL 怎么做,MySQL 耗費的 CPU 最少,但是一般不這么寫 SQL。

2)in:能夠命中索引。

示例代碼如下:

select * from doc where status in (1, 2)

查詢優化耗費的 CPU 比 union all 多,但可以忽略不計,一般情況下建議使用 in

3)or:新版的 MySQL 能夠命中索引。

示例代碼如下:

select * from doc where status = 1 or status = 2

查詢優化耗費的 CPU 比 in 多,不建議頻繁用 or。

3. 負向條件查詢不能使用索引,可以優化為 in 查詢。

負向條件有:!=、<>、not in、not exists、not like 等。

例如下面代碼:

select * from doc where status != 1 and status != 2

可以優化為 in 查詢:

select * from doc where status in (0,3,4)

4.聯合索引最左前綴原則(又叫最左側查詢)

1)如果在(a,b,c)三個字段上建立聯合索引,那么它能夠加快 a | (a,b) | (a,b,c) 三組查詢速度。

例如登錄業務需求,代碼如下。

select uid, login_time from user where login_name=? and passwd=?

可以建立(login_name, passwd)的聯合索引。

因為業務上幾乎沒有 passwd 的單條件查詢需求,而有很多 login_name 的單條件查詢需求,所以可以建立(login_name, passwd)的聯合索引,而不是(passwd, login_name)。

2)建聯合索引的時候,區分度最高的字段在最左邊。

3)如果建立了(a,b)聯合索引,就不必再單獨建立 a 索引。同理,如果建立了(a,b,c)聯合索引,就不必再單獨建立 a、(a,b) 索引。

4)存在非等號和等號混合判斷條件時,在建索引時,請把等號條件的列前置。如 where a>? and b=?,那么即使 a 的區分度更高,也必須把 b 放在索引的最前列。

5)最左側查詢需求,并不是指 SQL 語句的 where 順序要和聯合索引一致。

下面的 SQL 語句也可以命中 (login_name, passwd) 這個聯合索引。

select uid, login_time from user where passwd=? and login_name=?

但還是建議 where 后的順序和聯合索引一致,養成好習慣。

5. 范圍列可以用到索引(聯合索引必須是最左前綴)。

1)范圍條件有:、>=、between等。

2)范圍列可以用到索引(聯合索引必須是最左前綴),但是范圍列后面的列無法用到索引,索引最多用于一個范圍列,如果查詢條件中有兩個范圍列則無法全用到索引。

假如有聯合索引 (empno、title、fromdate),那么下面的 SQL 中 emp_no 可以用到索引,而 title 和 from_date 則使用不到索引。

select * from employees.titles where emp_no < 10010' and and from_date between '1986-01-01' and '1986-12-31'

6. 把計算放到業務層而不是數據庫層。

1)在字段上進行計算不能命中索引。

例如下面的 SQL 語句。

select * from doc where YEAR(create_time) <= '2016'

即使 date 上建立了索引,也會全表掃描,可優化為值計算,如下:

select * from doc where create_time <= '2016-01-01'

2)把計算放到業務層。

這樣做不僅可以節省數據庫的 CPU,還可以起到查詢緩存優化效果。

比如下面的 SQL 語句:

select * from order where date < = CURDATE()

可以優化為:

select * from order where date < = '2018-01-24 12:00:00'

優化后的 SQL 釋放了數據庫的 CPU 多次調用,傳入的 SQL 相同,才可以利用查詢緩存。7. 強制類型轉換會全表掃描

如果 phone 字段是 varchar 類型,則下面的 SQL 不能命中索引。

select * from user where phone=13800001234

可以優化為:

select * from user where phone='13800001234'

8. 更新十分頻繁、數據區分度不高的字段上不宜建立索引。

1)更新會變更 B+ 樹,更新頻繁的字段建立索引會大大降低數據庫性能。

2)“性別”這種區分度不大的屬性,建立索引是沒有什么意義的,不能有效過濾數據,性能與全表掃描類似。

3)一般區分度在80%以上的時候就可以建立索引,區分度可以使用 count(distinct(列名))/count(*) 來計算。

9. 利用覆蓋索引來進行查詢操作,避免回表。

被查詢的列,數據能從索引中取得,而不用通過行定位符 row-locator 再到 row 上獲取,即“被查詢列要被所建的索引覆蓋”,這能夠加速查詢速度。

例如登錄業務需求,代碼如下。

select uid, login_time from user where login_name=? and passwd=?

可以建立(login_name, passwd, login_time)的聯合索引,由于 login_time 已經建立在索引中了,被查詢的 uid 和 login_time 就不用去 row 上獲取數據了,從而加速查詢。

10. 如果有 order by、group by 的場景,請注意利用索引的有序性。

1)order by 最后的字段是組合索引的一部分,并且放在索引組合順序的最后,避免出現 file_sort 的情況,影響查詢性能。

2)例如對于語句 where a=? and b=? order by c,可以建立聯合索引(a,b,c)。

3)如果索引中有范圍查找,那么索引有序性無法利用,如 WHERE a>10 ORDER BY b;,索引(a,b)無法排序。

這篇文章介紹了MySQL索引的概念及10條優化規則,下篇文章會介紹第11~20條優化規則,并通過實例來驗證這些規則。

總結

以上是生活随笔為你收集整理的mysql范围条件_MySQL 索引及优化实战(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

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