惟一索引(unique index)
強調惟一,就是索引值必須惟一。mysql
create unique index [索引名] on 表名 (列名);
alter table 表名 add unique index [索引名] (列名);
刪除索引:
drop index 索引名 on 表名;
alter table 表名 drop index 索引名;程序員
主鍵
主鍵是一種特殊的惟一索引,主鍵要求建表時指定,通常用auto_increment列,關鍵字是primary keysql
creat table test2 (id int not null primary key auto_increment);數據庫
全文索引
InnoDB不支持,MyISAM支持性能比較好,通常在 CHAR、VARCHAR 或 TEXT 列上建立。緩存
Create table 表名(
id int not null primary key anto_increment,
title varchar(100),FULLTEXT(title)
)type=MyISAM;服務器
單列索引(普通索引)與多列索引(複合索引)
複合索引要注意"最左前綴原則"
"左前綴原則":在使用多列索引的時候 where中必須首先使用第一個索引(uname) 而後第二個(password) 第三個(..)
好比where uname="admin" and password="abc"
如下使用均起到到索引的效果:
where password="abc"
where password="abc" and uname="admin"
where uname="admin" or password="abc" (出現or則掃描全表)
create table test3 (
id int not null primary key auto_increment,
uname char(8) not null default '',
password char(12) not null,
INDEX(uname,password)
)type=MyISAM;
注意:INDEX(a, b, c)能夠當作a或(a, b)的索引來使用,但不能看成b、c或(b,c)的索引來使用。這是一個最左前綴的 優化方法,在後面會有詳細的介紹,你只要知道有這樣兩個概念。併發
聚簇索引性能
一種索引,該索引中鍵值的邏輯順序決定了表中相應行的物理順序。 聚簇索引肯定表中數據的物理順序。Mysql中MyISAM 表是沒有聚簇索引的,innodb有(主鍵就是聚簇索引)測試
查看錶索引
show index from tableName;優化
表數據類型選擇
1.能小就用小。表數據類型第一個原則是:使用能正確的表示和存儲數據的最短類型。這樣能夠減小對磁盤空間、內存、cpu緩存的使用。
2.避免用NULL,這個也是網上優化技術博文傳的最多的一個。理由是額外增長字節,還有使索引,索引統計和值更復雜。不少還忽略一 個count(列)的問題,count(列)是不會統計列值爲null的行數。
3.Tinyint、smallint、mediumint、int、bigint,分別須要八、1六、2四、3二、64。
值域範圍:-2 (n-1)~ 2 (n-1)-1
不少程序員在設計數據表的時候很習慣的用int,壓根不考慮這個問題
筆者建議:能用tinyint的毫不用smallint
誤區:int(1) 和int(11)是同樣的,惟一區別是mysql客戶端顯示的時候顯示多少位。
整形優先原則:能用整形的不用其餘類型替換,如ip能夠轉換成整形保存,如商品價格‘50.00元’則保存成50
4.精確度與空間的轉換。在存儲相同數值範圍的數據時,浮點數類型一般都會比DECIMAL類型使用更少的空間。FLOAT字段使用4 字節存儲 數據。DOUBLE類型須要8 個字節並擁有更高的精確度和更大的數值範圍,DECIMAL類型的數據將會轉換成DOUBLE類型。
建立一個表:
create table one (
id smallint(10) not null auto_increment primary key,
username char(8) not null,
password char(4) not null,
`level` tinyint (1) default 0,
last_login char(15) not null,
index (username,password,last_login)
) engine=innodb;
分析sql語句執行狀況:
explain 關鍵字
explain select * from one where last_login +1= 8388606 ; (錯誤用法)
explain select * from one where last_login = 8388607 ; (正確用法)
索引字段上使用表達式將失去索引效果
索引選擇性
索引選擇性是不重複的索引值也叫基數(cardinality)表中數據行數的比值,索引選擇性=基數/數據行,基數能夠經過 「show index from 表名」查看。高索引選擇性的好處就是mysql查找匹配的時候能夠過濾更多的行,惟一索引的選擇性最佳,值爲1。 那麼對於非惟一索引或者說要被建立索引的列的數據內容很長,那就要選擇索引前綴。這裏就簡單說明一下:
mysql> select count(distinct(username))/count(*) from one;
+------------------------------------+
| count(distinct(username))/count(*) |
+------------------------------------+
| 0.2047 |
+------------------------------------+
1 row in set (0.09 sec)
count(distinct(username))/count( )就是索引選擇性,這裏0.2過小了。假如username列數據很長,則能夠經過 select count(distinct(concat(first_name, left(last_name, N))/count( ) from one;測試出接近1的索引選擇性, 其中N是索引的長度,窮舉法去找出N的值,而後再建索引。
系統配置與維護優化
重要的一些變量
key_buffer_size索引塊緩存區大小, 針對MyISAM存儲引擎,該值越大,性能越好.可是超過操做系統能承受的最大值,反而會使mysql變得不穩定. ----這是很重要的參數
sort_buffer_size 這是索引在排序緩衝區大小,若排序數據大小超過該值,則建立臨時文件,注意和MyISAM_sort_buffer_size的區別----這是很重要的參數
read_rnd_buffer_size當排序後按排序後的順序讀取行時,則經過該緩衝區讀取行,避免搜索硬盤。將該變量設置爲較大的值能夠大大改進ORDER BY的性能。可是,這是爲每一個客戶端分配的緩衝區,所以你不該將全局變量設置爲較大的值。相反,只爲須要運行大查詢的客戶端更改會話變量
join_buffer_size用於表間關聯(join)的緩存大小
tmp_table_size緩存表的大小
table_cache容許 MySQL 打開的表的最大個數,而且這些都cache在內存中
delay_key_write針對MyISAM存儲引擎,延遲更新索引.意思是說,update記錄時,先將數據up到磁盤,但不up索引,將索引存在內存裏,當表關閉時,將內存索引,寫到磁盤
optimize、Analyze、check、repair維護操做
optimize 數據在插入,更新,刪除的時候不免一些數據遷移,分頁,以後就出現一些碎片,長此以往碎片積累起來影響性能, 這就須要DBA按期的優化數據庫減小碎片,這就經過optimize命令。如對MyISAM表操做:optimize table 表名
對於InnoDB表是不支持optimize操做,不然提示「Table does not support optimize, doing recreate + analyze instead」, 固然也能夠經過命令:alter table one type=innodb; 來替代。
Analyze 用來分析和存儲表的關鍵字的分佈,使得系統得到準確的統計信息,影響 SQL 的執行計劃的生成。對於數據基本沒有發生 變化的表,是不須要常常進行表分析的。可是若是表的數據量變化很明顯,用戶感受實際的執行計劃和預期的執行計劃不 同的時候, 執行一次表分析可能有助於產生預期的執行計劃。Analyze table 表名
Check檢查表或者視圖是否存在錯誤,對 MyISAM 和 InnoDB 存儲引擎的表有做用。對於 MyISAM 存儲引擎的表進行表檢查, 也會同時更新關鍵字統計數據
Repair optimize須要有足夠的硬盤空間,不然可能會破壞表,致使不能操做,那就要用上repair,注意INNODB不支持repair操做
表結構的更新與維護
改表結構。當要在數據量千萬級的數據表中使用alter更改表結構的時候,這是一個棘手問題。一種方法是在低併發低訪問量的時 候用日常的alter更改表。另一種就是建另外一個與要修改的表,這個表除了要修改的結構屬性外其餘的和原表如出一轍,這樣就 能獲得一個相應的.frm文件,而後用flush with read lock 鎖定讀,而後覆蓋用新建的.frm文件覆蓋原表的.frm, 最後unlock table 釋放表。
創建新的索引。通常方法這裏不說。
建立沒索引的a表,導入數據造成.MYD文件。
建立包括索引b表,造成.FRM和.MYI文件
鎖定讀寫
把b表的.FRM和.MYI文件改爲a表名字
解鎖
用repair建立索引。
這個方法對於大表也是頗有效的。這也是爲何不少dba堅持說「先導數據庫在建索引,這樣效率更快」
按期檢查mysql服務器 按期使用show status、show processlist等命令檢查數據庫。這裏就不細說,這提及來也篇幅是比較大的,筆者對這個也不是很瞭解