mysql次級索引 MySQL 索引總結

2021-10-19 19:39:52 字數 4560 閱讀 1231

1、索引是做什麼的?

想象一下,你面前有本詞典,資料就是書的正文內容,你就是那個cpu,而索引,則是書的目錄

索引用於快速找出在某個列中有一特定值的行。不使用索引,mysql必須從第1條記錄開始然後讀完整個表直到找出相關的行。

表越大,花費的時間越多。如果表中查詢的列有乙個索引,mysql能快速到達乙個位置去搜尋到資料檔案的中間,沒有必要看所有資料。

大多數mysql索引(primary key、unique、index和fulltext)在b樹中儲存。只是空間列型別的索引使用r-樹,並且memory表還支援hash索引。

2、索引越多越好?

大多數情況下索引能大幅度提高查詢效率,但:

資料的變更(增刪改)都需要維護索引,因此更多的索引意味著更多的維護成本

更多的索引意味著也需要更多的空間 (一本100頁的書,卻有50頁目錄?)

過小的表,建索引可能會更慢 (讀個2頁的宣傳手冊,你還先去找目錄?)

3、索引的字段型別問題

text型別,也可建索引(需指定長度)

myisam儲存引擎索引鍵長度綜合不能超過1000位元組

用來篩選的值盡量保持和索引列同樣的資料型別

儘量減少like,但不是絕對不可用,"***x%" 是可以用到索引的,

想象一下,你在看一本成語詞典,目錄是按成語拼音順序建立,查詢需求是,你想找以 "一"字開頭的成語("一%"),和你想找包含一字的成語("%一%")

除了like,以下操作符也可用到索引:

,>=,between,in

<>,not in ,!=則不行

null會導致索引形同虛設,所以在設計表結構時應避免null 的存在(用其他方式表達你想表達的null,比如 -1?)

4、什麼樣的字段不適合建索引?

一般來說,列的值唯一性太小(如性別,型別什麼的),不適合建索引(怎樣叫太小?一半說來,同值的資料超過表的百分之15,那就沒必要建索引了)

太長的列,可以選擇只建立部分索引,(如:只取前十位做索引)

更新非常頻繁的資料不適宜建索引

5、如何檢視索引資訊,如何分析是否正確用到索引?

show index from tablename;

explain select ……;

關於explain,改天可以找個時間專門寫一篇入門帖,在此之前,可以嘗試 google

6、開啟查詢快取

show variables like '%cache%';

query_cache_type為off,在配置檔案/etc/my.cf中新增「query_cache_type = 1」配置項並重啟。

7、當只要一行資料時使用 limit 1

8、在join表的時候使用相當型別的例,並將其索引

如果你的應用程式有很多 join 查詢,你應該確認兩個表中join的字段是被建過索引的。這樣,mysql內部會啟動為你優化join的sql語句的機制。

而且,這些被用來join的字段,應該是相同的型別的。例如:如果你要把 decimal 欄位和乙個 int 欄位join在一起,mysql就無法使用它們的索引。對於那些string型別,還需要有相同的字符集才行。(兩個表的字符集有可能不一樣)

9、千萬不要 order by rand()

想打亂返回的資料行?隨機挑乙個資料?真不知道誰發明了這種用法,但很多新手很喜歡這樣用。但你確不了解這樣做有多麼可怕的效能問題。

如果你真的想把返回的資料行打亂了,你有n種方法可以達到這個目的。這樣使用只讓你的資料庫的效能呈指數級的下降。這裡的問題是:mysql會不得 不去執行rand()函式(很耗cpu時間),而且這是為了每一行記錄去記行,然後再對其排序。就算是你用了limit 1也無濟於事(因為要排序)

10、永遠為每張表設定乙個id

我們應該為資料庫裡的每張表都設定乙個id做為其主鍵,而且最好的是乙個int型的(推薦使用unsigned),並設定上自動增加的auto_increment標誌。

就算是你 users 表有乙個主鍵叫 「email」的字段,你也別讓它成為主鍵。使用 varchar 型別來當主鍵會使用得效能下降。另外,在你的程式中,你應該使用表的id來構造你的資料結構。

而且,在mysql資料引擎下,還有一些操作需要使用主鍵,在這些情況下,主鍵的效能和設定變得非常重要,比如,集群,分割槽……

在這裡,只有乙個情況是例外,那就是「關聯表」的「外來鍵」,也就是說,這個表的主鍵,通過若干個別的表的主鍵構成。我們把這個情況叫做「外來鍵」。比 如:有乙個「學生表」有學生的id,有乙個「課程表」有課程id,那麼,「成績表」就是「關聯表」了,其關聯了學生表和課程表,在成績表中,學生id和課 程id叫「外來鍵」其共同組成主鍵。

11、使用 enum 而不是 varchar

enum 型別是非常快和緊湊的。在實際上,其儲存的是 tinyint,但其外表上顯示為字串。這樣一來,用這個欄位來做一些選項列表變得相當的完美。

12、從 procedure analyse() 取得建議

procedure analyse() 會讓 mysql 幫你去分析你的字段和其實際的資料,並會給你一些有用的建議。只有表中有實際的資料,這些建議才會變得有用,因為要做一些大的決定是需要有資料作為基礎的。

13、prepared statements

procedure analyse() ,在優化表結構時可以輔助參考分析語句。通過分析select查詢結果對現有的表的每一列給出優化的建議

14、無緩衝的查詢

正常的情況下,當你在當你在你的指令碼中執行乙個sql語句的時候,你的程式會停在那裡直到沒這個sql語句返回,然後你的程式再往下繼續執行。你可以使用無緩衝查詢來改變這個行為。

mysql_unbuffered_query() 傳送乙個sql語句到mysql而並不像mysql_query()一樣去自動fethch和快取結果。這會相當節約很多可觀的記憶體,尤其是那些會產生大 量結果的查詢語句,並且,你不需要等到所有的結果都返回,只需要第一行資料返回的時候,你就可以開始馬上開始工作於查詢結果了。

然而,這會有一些限制。因為你要麼把所有行都讀走,或是你要在進行下一次的查詢前呼叫 mysql_free_result() 清除結果。而且, mysql_num_rows() 或 mysql_data_seek() 將無法使用。所以,是否使用無緩衝的查詢你需要仔細考慮。

15、固定長度的表會更快

如果表中的所有欄位都是「固定長度」的,整個表會被認為是 「static」 或 「fixed-length」。 例如,表中沒有如下型別的字段: varchar,text,blob。只要你包括了其中乙個這些字段,那麼這個表就不是「固定長度靜態表」了,這樣,mysql 引擎會用另一種方法來處理。

固定長度的表會提高效能,因為mysql搜尋得會更快一些,因為這些固定的長度是很容易計算下乙個資料的偏移量的,所以讀取的自然也會很快。而如果字段不是定長的,那麼,每一次要找下一條的話,需要程式找到主鍵。

並且,固定長度的表也更容易被快取和重建。不過,唯一的***是,固定長度的字段會浪費一些空間,因為定長的字段無論你用不用,他都是要分配那麼多的空間。

使用「垂直分割」技術(見下一條),你可以分割你的表成為兩個乙個是定長的,乙個則是不定長的。

17、垂直分割

「垂直分割」是一種把資料庫中的表按列變成幾張表的方法,這樣可以降低表的複雜度和字段的數目,從而達到優化的目的。(以前,在銀行做過專案,見過一張表有100多個字段,很恐怖)

示例一:在users表中有乙個欄位是家庭位址,這個欄位是可選字段,相比起,而且你在資料庫操作的時候除了個人資訊外,你並不需要經常讀取或是改 寫這個字段。那麼,為什麼不把他放到另外一張表中呢? 這樣會讓你的表有更好的效能,大家想想是不是,大量的時候,我對於使用者表來說,只有使用者id,使用者名稱,口令,使用者角色等會被經常使用。小一點的表總是會有 好的效能。

示例二: 你有乙個叫 「last_login」 的字段,它會在每次使用者登入時被更新。但是,每次更新時會導致該錶的查詢快取被清空。所以,你可以把這個字段放到另乙個表中,這樣就不會影響你對使用者 id,使用者名稱,使用者角色的不停地讀取了,因為查詢快取會幫你增加很多效能。

另外,你需要注意的是,這些被分出去的字段所形成的表,你不會經常性地去join他們,不然的話,這樣的效能會比不分割時還要差,而且,會是極數級的下降。

18、mysql強制索引和禁止某個索引

1、mysql強制使用索引:force index(索引名或者主鍵pri)

select * from table force index(pri) limit 2;(強制使用主鍵)

select * from table force index(ziduan1_index) limit 2;(強制使用索引」ziduan1_index」)

select * from table force index(pri,ziduan1_index) limit 2;(強制使用索引」pri和ziduan1_index」)

2、mysql禁止某個索引:ignore index(索引名或者主鍵pri)

select * from table ignore index(pri) limit 2;(禁止使用主鍵)

select * from table ignore index(ziduan1_index) limit 2;(禁止使用索引」ziduan1_index」)

select * from table ignore index(pri,ziduan1_index) limit 2;(禁止使用索引」pri,ziduan1_index」)

mysql 雜湊索引 MySQL索引之雜湊索引

雜湊索引 hash index 建立在雜湊表的基礎上,它只對使用了索引中的每一列的精確查詢有用。對於每一行,儲存引擎計算出了被索引的雜湊碼 hash code 它是乙個較小的值,並且有可能和其他行的雜湊碼不同。它把雜湊碼儲存在索引中,並且儲存了乙個指向雜湊表中的每一行的指標。在mysql中,只有me...

mysql主鍵索引 MySQL索引之主鍵索引

在mysql裡,主鍵索引和輔助索引分別是什麼意思,有什麼區別?上次的分享我們介紹了聚集索引和非聚集索引的區別,本次我們繼續介紹主鍵索引和輔助索引的區別。1 主鍵索引 主鍵索引,簡稱主鍵,原文是primary key,由乙個或多個列組成,用於唯一性標識資料表中的某一條記錄。乙個表可以沒有主鍵,但最多只...

mysql聚集索引 MySQL索引之聚集索引介紹

在mysql裡,聚集索引和非聚集索引分別是什麼意思,有什麼區別?在mysql中,innodb引擎表是 聚集 索引組織表 clustered index organize table 而myisam引擎表則是堆組織表 heap organize table 也有人把聚集索引稱為聚簇索引。當然了,聚集索...