當資料庫中的資料量達到億級,數十億級的時候,普通的一條查詢語句都可能耗時非常長,解決此問題的乙個有效方法是有效的建立索引。
合理的建立索引能夠加速資料讀取效率,不合理的建立索引反而會拖慢資料庫的響應速度
索引越多,更新資料的速度越慢
盡量在採用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的索引型別...