來自http://www.cnblogs.com/DaBing0806/p/4876228.html
索引用于快速找出在某個列中有一特定值的行。不使用索引,MySQL必須從第1條記錄開始然后讀完整個表直到找出相關的行,還需要考慮每次讀入數據頁的IO開銷。而如果采取索引,則可以根據索引指向的頁以及記錄在頁中的位置,迅速地讀取目標頁進而獲取目標記錄。
大多數情況下都(默認)采用B樹來構建索引。只是空間列類型的索引使用R-樹,并且MEMORY表還支持hash索引。B樹是平衡多叉樹,每個節點存放多少個值取決于值所占的空間,這與每一張數據頁存放多少條記錄與記錄信息量有關同理。節點中的值是以非降序進行排列的,節點中的值總是小于等于指向它的結點中的值。
MySQL使用B樹構造索引的情況下,是由葉子指向具體的頁和記錄的。并且一個葉子有一個指針指向下一個葉子。
**使用索引需要注意:**
⑴只對WHERE和ORDER BY需要查詢的字段設置索引,避免無意義的硬盤開銷;
⑵組合索引支持前綴索引;
⑶更新表的時候,如增刪記錄,MySQL會自動更新索引,保持樹的平衡;因此更多的索引意味著**更多的維護成本**
**?索引的字段類型問題**
* text類型,也可建索引(需指定長度)
* myisam存儲引擎索引鍵長度綜合不能超過1000字節
* 用來篩選的值盡量保持和索引列同樣的數據類型
**索引分四類:**
index ----普通的索引,數據可以重復
fulltext----全文索引,用來對大表的文本域(char,varchar,text)進行索引。語法和普通索引一樣。?
unique ----唯一索引,唯一索引,要求所有記錄都唯一
primary key ----主鍵索引,也就是在唯一索引的基礎上相應的列必須為主鍵
**like 不能用索引?**
* 盡量減少like,但不是絕對不可用,”xxxx%” 是可以用到索引的,
想象一下,你在看一本成語詞典,目錄是按成語拼音順序建立,查詢需求是,你想找以 “一”字開頭的成語(”一%“),和你想找包含一字的成語(“%一%”)
* 除了like,以下操作符也可用到索引:
,>=,BETWEEN,IN
<>,not in ,!=則不行
**原則**
1,單表數據太少,索引反而會影響速度;更新非常頻繁的數據不適宜建索引
?2,where后的條件,order by ,group by 等這樣過濾時,后面的字段最好加上索引。根據實際情況,選擇PRIMARY KEY、UNIQUE、INDEX等索引,但是不是越多越好,要適度
? ? 3,聯合查詢,子查詢等多表操作時關連字段要加索引
ps:數據量特別大的時候,最好不要用聯合查詢,即使你做了索引
## 多列查詢該如何建索引?
一次查詢只能用到一個索引,所以 首先槍斃 a,b各建索引方案
a還是b? 誰的區分度更高(同值的最少),建誰!
當然,聯合索引也是個不錯的方案,ab,還是ba,則同上,區分度高者,在前
## 聯合索引的問題?
where a = “xxx” 可以使用 AB 聯合索引
where b = “xxx” 則不可 (再想象一下,這是書的目錄?)
所以,大多數情況下,有AB索引了,就可以不用在去建一個A索引了
**詳解:**
聯合索引又叫復合索引。對于復合索引:Mysql從左到右的使用索引中的字段,一個查詢可以只使用索引中的一部份,但只能是最左側部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3種組合進行查找,但不支持 b,c進行查找 .當最左側字段是常量引用時,索引就十分有效。
兩個或更多個列上的索引被稱作復合索引。
利用索引中的附加列,您可以縮小搜索的范圍,但使用一個具有兩列的索引 不同于使用兩個單獨的索引。復合索引的結構與電話簿類似,人名由姓和名構成,電話簿首先按姓氏對進行排序,然后按名字對有相同姓氏的人進行排序。如果您知 道姓,電話簿將非常有用;如果您知道姓和名,電話簿則更為有用,但如果您只知道名不姓,電話簿將沒有用處。
所以說創建復合索引時,應該仔細考慮列的順序。對索引中的所有列執行搜索或僅對前幾列執行搜索時,復合索引非常有用;僅對后面的任意列執行搜索時,復合索引則沒有用處。
如:建立 姓名、年齡、性別的復合索引。
create table test(
a int,
b int,
c int,
KEY a(a,b,c)
);
優: select * from test where a=10 and b>50
差: select * from test where a50
優: select * from test order by a
差: select * from test order by b
差: select * from test order by c
優: select * from test where a=10 order by a
優: select * from test where a=10 order by b
差: select * from test where a=10 order by c
優: select * from test where a>10 order by a
差: select * from test where a>10 order by b
差: select * from test where a>10 order by c
優: select * from test where a=10 and b=10 order by a
優: select * from test where a=10 and b=10 order by b
優: select * from test where a=10 and b=10 order by c
優: select * from test where a=10 and b=10 order by a
優: select * from test where a=10 and b>10 order by b
差: select * from test where a=10 and b>10 order by c
索引原則
1.索引越少越好
原因:主要在修改數據時,第個索引都要進行更新,降低寫速度。
2.最窄的字段放在鍵的左邊
3.避免file sort排序,臨時表和表掃描.
## 哪些常見情況不能用索引?
* like “%xxx”
* not in , !=
* 對列進行函數運算的情況(如 where md5(password) = “xxxx”)
* WHERE index=1 OR A=10
* 存了數值的字符串類型字段(如手機號),查詢時記得不要丟掉值的引號,否則無法用到該字段相關索引,反之則沒關系
也即
select * from test where mobile = 13711112222;
可是無法用到mobile字段的索引的哦(如果mobile是char 或 varchar類型的話)
btw,**千萬不要嘗試用int來存手機號**(為什么?自己想!要不自己試試)
## 覆蓋索引(Covering Indexes)擁有更高效率
索引包含了所需的全部值的話,就只select 他們,換言之,只select 需要用到的字段,如無必要,可盡量避免select *
## NULL 的問題
NULL會導致索引形同虛設,所以在設計表結構時應避免NULL 的存在(用其他方式表達你想表達的NULL,比如 -1?)
## 如何查看索引信息,如何分析是否正確用到索引?
show index from tablename;
explain select ……;
關于explain,改天可以找個時間專門寫一篇入門帖,在此之前,可以嘗試 google
## 了解自己的系統,不要過早優化!
過早優化,一直是個非常討厭而又時刻存在的問題,大多數時候就是因為不了解自己的系統,不知道自己系統真正的承載能力
比如:幾千條數據的新聞表,每天幾百幾千次的正文搜索,大多數時候我們可以放心的去like,而不要又去建一套全文搜索什么的,畢竟cpu還是比人腦厲害太多
## 最后:**永遠別忘記的關鍵詞[?sql注入](http://baike.baidu.com/view/3896.htm)**
- 數據庫
- CAP定理
- 關系模型
- 關系數據庫
- NoSQL
- ODBC
- JDBC
- ODBC、JDBC和四種驅動類型
- mysql
- 安裝與配置
- CentOS 7 安裝 MySQL
- 優化
- 比較全面的MySQL優化參考
- 1、硬件層相關優化
- 1.1、CPU相關
- 1.2、磁盤I/O相關
- 2、系統層相關優化
- 2.1、文件系統層優化
- 2.2、其他內核參數優化
- 3、MySQL層相關優化
- 3.1、關于版本選擇
- 3.2、關于最重要的參數選項調整建議
- 3.3、關于Schema設計規范及SQL使用建議
- 3.4、其他建議
- 后記
- Mysql設計與優化專題
- ER圖,數據建模與數據字典
- 數據中設計中的范式與反范式
- 字段類型與合理的選擇字段類型
- 表的垂直拆分和水平拆分
- 詳解慢查詢
- mysql的最佳索引攻略
- 高手詳解SQL性能優化十條經驗
- 優化SQL查詢:如何寫出高性能SQL語句
- MySQL索引原理及慢查詢優化
- 數據庫SQL優化大總結之 百萬級數據庫優化方案
- 數據庫性能優化之SQL語句優化1
- 【重磅干貨】看了此文,Oracle SQL優化文章不必再看!
- MySQL 對于千萬級的大表要怎么優化?
- MySQL 數據庫設計總結
- MYSQL性能優化的最佳20+條經驗
- 數據操作
- 數據語句操作類型
- DCL
- 修改Mysql數據庫名的5種方法
- DML
- 連接
- 連接2
- DDL
- 數據類型
- 字符集
- 表引擎
- 索引
- MySQL理解索引、添加索引的原則
- mysql建索引的幾大原則
- 淺談mysql的索引設計原則以及常見索引的區別
- 常用工具簡介
- QA
- MySQL主機127.0.0.1與localhost區別總結
- 視圖(view)
- 觸發器
- 自定義函數和存儲過程的使用
- 事務(transaction)
- 范式與反范式
- 常用函數
- MySQL 數據類型 詳解
- Mysql數據庫常用分庫和分表方式
- 隔離級別
- 五分鐘搞清楚MySQL事務隔離級別
- mysql隔離級別及事務傳播
- 事務隔離級別和臟讀的快速入門
- 數據庫引擎中的隔離級別
- 事務隔離級別
- Innodb中的事務隔離級別和鎖的關系
- MySQL 四種事務隔離級的說明
- Innodb鎖機制:Next-Key Lock 淺談
- SQL函數和存儲過程的區別
- mongo
- MongoDB設置訪問權限、設置用戶
- redis
- ORM
- mybatis
- $ vs #
- mybatis深入理解(一)之 # 與 $ 區別以及 sql 預編譯
- 電商設計
- B2C電子商務系統研發——概述篇
- B2C電子商務系統研發——商品數據模型設計
- B2C電子商務系統研發——商品模塊E-R圖建模
- B2C電子商務系統研發——商品SKU分析和設計(一)
- B2C電子商務系統研發——商品SKU分析和設計(二)
- 數據庫命名規范--通用