MySQL 有效的建立索引

2021-07-05 23:15:04 字數 4287 閱讀 8453

當資料庫中的資料量達到億級,數十億級的時候,普通的一條查詢語句都可能耗時非常長,解決此問題的乙個有效方法是有效的建立索引

合理的建立索引能夠加速資料讀取效率,不合理的建立索引反而會拖慢資料庫的響應速度

索引越多,更新資料的速度越慢

盡量在採用myisam作為儲存引擎的時候使用索引(因為mysql以btree儲存索引),而不是innodb,但是mysaim不支援transcation

當你的程式和資料庫結構/sql語句已經優化到無法優化的程度,而程式瓶頸並不能順利解決,那就是應該考慮使用諸如memcached這樣的分布式快取系統的時候了。

習慣和強迫自己用explain來分析你sql語句的效能。

ps:不要在選擇的字段上放置索引,這是無意義的。應該在條件選擇的語句上合理的放置索引,比如where,order by。

例子:

select id,title,content,cat_id from article where cat_id = 1;
上面這個語句,你在id/title/content上放置索引是毫無意義的,對這個語句沒有任何優化作用。但是如果你在外鍵cat_id上放置乙個索引,那作用就相當大了。

1、order by + limit組合的索引優化。

如果乙個sql語句形如:

select

[column1],[column2],....

from dbname

order by [sort]

limit [offset],[limit];

這個sql語句優化比較簡單,在[sort]這個欄位上建立索引即可。

2、where + order by + limit組合的索引優化,形如:

select [column1],[column2],.... 

from

where [columnx] = [value]

order

by [sort]

limit[offset],[limit];

這個語句,如果你仍然採用第乙個例子中建立索引的方法,雖然可以用到索引,但是效率不高。更高效的方法是建立乙個聯合索引(columnx,sort)

3、where + in + order by + limit組合的索引優化,形如:

select [column1],[column2],.... 

from

where [columnx] in ([value1],[value2],...)

order by[sort]

limit [offset],[limit];

這個語句如果你採用第二個例子中建立索引的方法,會得不到預期的效果(僅在[sort]上是using index,where那裡是using where;using filesort),理由是這裡對應columnx的值對應多個。

這個語句怎麼優化呢?我暫時沒有想到什麼好的辦法,看到網上有便宜提供的辦法,那就是將這個語句用union分拆,然後建立第二個例子中的索引:

select [column1],[column2],.... 

from

where [columnx]=[value1]

order

by [sort]

limit[offset],[limit]

union

select [column1],[column2],....

from

where [columnx]=[value2]

order

by [sort]

limit[offset],[limit]

union

但經驗證,這個方法根本行不通,效率反而更低,測試時對於大部分應用強制指定使用排序索引效果更好點

4、不要再where和order by的字段上應用表示式(函式),比如:

select * from

order

byyear(date) limit 0,30;

5、where+order by多個欄位+limit,比如

select * from

where uid=1

order

by x,y limit 0,10;

對於這個語句,大家可能是加乙個這樣的索引(x,y,uid)。但實際上更好的效果是(uid,x,y)。這是由mysql處理排序的機制造成的。

以上例子你在實際專案中應用的時候,不要忘記在新增索引後,用explain看看效果。

另外注意:

索引的字段型別要一致

一般來說,不應該建立索引的的這些列具有下列特點:

mysql目前提供4種索引。

4.1 mysql如何使用索引

b-tree——balanced tree,平衡樹,不是二叉樹(binary tree)

1.新增primary key(主鍵索引) 

alter

table

`table_name`

addprimary

key ( `column` )

2.新增unique(唯一索引)

alter

table

`table_name`

addunique ( `column` )

3.新增index(普通索引)

alter

table

`table_name`

add index index_name ( `column` )

4.新增fulltext(全文索引)

alter

table

`table_name`

add fulltext ( `column`)

5.新增多列索引

alter

table

`table_name`

add index index_name ( `column1`, `column2`, `column3` )

4.2 mysql中能夠使用索引的典型場景

全值匹配

explain select cpu_use_rate

from terminal_data_file

where cpu_use_rate = 90

possible_keys

顯示可能應用在這張表中的索引。如果為空,沒有可能的索引。可以為相關的域從where語句中選擇乙個合適的語句

key

實際使用的索引。如果為null,則沒有使用索引。很少的情況下,mysql會選擇優化不足的索引。這種情況下,可以在select語句中使用use index(indexname)來強制使用乙個索引或者用ignore index(indexname)來強制mysql忽略索引

key_len

使用的索引的長度。在不損失精確性的情況下,長度越短越好

ref

顯示索引的哪一列被使用了,如果可能的話,是乙個常數

rows

mysql認為必須檢查的用來返回請求資料的行數

extra

關於mysql如何解析查詢的額外資訊。將在表中討論,但這裡可以看到的壞的例子是using temporary和using filesort,意思mysql根本不能使用索引,結果是檢索會很慢

匹配值的範圍查詢

explain

select cpu_use_rate

from terminal_data_file

where cpu_use_rate > 85

匹配最左字首(match a leftmost prefix)

僅僅使用最左邊列進行查詢,如(col1,col2,col3)欄位上的聯合索引能被包含col1,(col1+col2),(col1+col2+col3)的等值查詢利用到,可是不能被col2,(col2+col3)的等值查詢利用到

僅僅對索引進行查詢

匹配列字首(match a column prefix)

能夠實現索引匹配部分精確而其他部分進行範圍匹配

如果列名是索引,那麼使用column_name is null 就會使用索引

mysql 5.6 引入 index condition pushdown (icp)

(索引)建立MySQL索引

建立索引的必要性 主鍵預設是建立索引的,而且具有唯一性 合適地建立索引後比不建立索引,提高了查詢速度 建立索引的語法 簡單索引 可以有重複資料 create index indexname on tablename column name 1舉例子說明如 建立乙個資料表,設定一些初始的資料,然後採用...

c mysql建立索引 MySQL 建立索引

1 索引建立原則 1 搜尋的索引列,不一定是所要選擇的列。換句話說,最適合索引的列是出現在where子句中的列,或連線子句中指定的列,而不是出現在select關鍵字後的選擇列表中的列。2 使用唯一索引。考慮某列中值的分布。索引的列的基數越大,索引的效果越好。3 使用短索引。如果對字串列進行索引,應該...

mysql 索引的建立

建立索引語法 create unique fulltext spatial index index name using index type on table name index col nam,index col name col name length asc desc mysql的索引型別...