1. 程式人生 > >mysql基礎(四)之索引

mysql基礎(四)之索引

name 根據 正是 而不是 方案 加速 .com mtab 技術

索引簡介:

技術分享
1、普通索引

  普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對數據的訪問速度。因此,應該只為那些最經常出現在查詢條件 (WHEREcolumn=)或排序條件(ORDERBYcolumn)中的數據列創建索引。只要有可能,就應該選擇一個數據最整齊、最緊湊的數據列(如 一個整數類型的數據列)來創建索引。

  2、唯一索引

  普通索引允許被索引的數據列包含重復的值。比如說,因為人有可能同名,所以同一個姓名在同一個“員工個人資料”數據表裏可能出現兩次或更多次。

  如果能確定某個數據列將只包含彼此各不相同的值,在為這個數據列創建索引的時候就應該用關鍵字UNIQUE把它定義為一個唯一索引。這麽做的好 處:一是簡化了MySQL對這個索引的管理工作,這個索引也因此而變得更有效率;二是MySQL會在有新記錄插入數據表時,自動檢查新記錄的這個字段的值
    是否已經在某個記錄的這個字段裏出現過了;如果是,MySQL將拒絕插入那條新記錄。也就是說,唯一索引可以保證數據記錄的唯一性。
     事實上,在許多場合, 人們創建唯一索引的目的往往不是為了提高訪問速度,而只是為了避免數據出現重復。

  
3、主索引   在前面已經反復多次強調過:必須為主鍵字段創建一個索引,這個索引就是所謂的“主索引”。主索引與唯一索引的唯一區別是:前者在定義時使用的關鍵字是PRIMARY而不是UNIQUE。   4、外鍵索引   如果為某個外鍵字段定義了一個外鍵約束條件,MySQL就會定義一個內部索引來幫助自己以最有效率的方式去管理和使用外鍵約束條件。   5、復合索引   索引可以覆蓋多個數據列,如像INDEX(columnA,columnB)索引。這種索引的特點是MySQL可以有選擇地使用一個這樣的索 引。如果查詢操作只需要用到columnA數據列上的一個索引,就可以使用復合索引INDEX(columnA,columnB)。不過,這種用法僅適用 於在復合索引中排列在前的數據列組合。比如說,INDEX(A,B,C)可以當做A或(A,B)的索引來使用,但不能當做B、C或(B,C)的索引來使 用。   
6、索引的長度   在為CHAR和VARCHAR類型的數據列定義索引時,可以把索引的長度限制為一個給定的字符個數(這個數字必須小於這個字段所允許的最大字符 個數)。這麽做的好處是可以生成一個尺寸比較小、檢索速度卻比較快的索引文件。 在絕大多數應用裏,數據庫中的字符串數據大都以各種各樣的名字為主,把索引 的長度設置為10~15個字符已經足以把搜索範圍縮小到很少的幾條數據記錄了。 在為BLOB和TEXT類型的數據列創建索引時,必須對索引的長度做出限 制;MySQL所允許的最大索引全文索引文本字段上的普通索引只能加快對出現在字段內容最前面的字符串(也就是字段內容開頭的字符)進行檢索操作。 如果字 段裏存放的是由幾個、甚至是多個單詞構成的較大段文字,普通索引就沒什麽作用了。這種檢索往往以的形式出現,這對MySQL來說很復雜,如果需要處理的數 據量很大,響應時間就會很長。   這類場合正是全文索引(full
-textindex)可以大顯身手的地方。在生成這種類型的索引時,MySQL將把在文本中出現的所有單詞創 建為一份清單,查詢操作將根據這份清單去檢索有關的數據記錄。全文索引即可以隨數據表一同創建,也可以等日後有必要時再使用下面這條命令添加:   ALTERTABLEtablenameADDFULLTEXT(column1,column2)有了全文索引,就可以用SELECT查詢命令去檢索那些包含著一個或多個給定單詞的數據記錄了。下面是這類查詢命令的基本語法:   SELECT*FROMtablename   WHEREMATCH(column1,column2)AGAINST(‘word1‘,‘word2‘,‘word3’)   上面這條命令將把column1和column2字段裏有word1、word2和word3的數據記錄全部查詢出來。
View Code
參考博客: http://www.cnblogs.com/wupeiqi/articles/5716963.html

索引是表的目錄,在查找內容之前可以先在目錄中查找索引位置,以此快速定位查詢數據。對於索引,會保存在額外的文件中。

索引: 作用: 加速查找 約束
1 普通索引 僅加速查詢
2 主鍵索引 加速查詢 + 列值唯一 + 表中只有一個(不可以有null)
3 唯一索引 加速查詢 + 列值唯一(可以有null)
create table t1(
id int ....,
num int,
xx int,
unique 唯一索引名稱 (列名,列名),
constraint ....
)
作用:加速查找
不能重復 可以為空 可以設置多行為唯一索引(聯合唯一)
ps 主鍵不能為空
4 聯合索引:(多列)
聯合唯一索引
聯合主鍵索引
聯合普通索引
5 全文索引:對文本的內容進行分詞,進行搜索


無索引:從數據庫中從前往後依次查找
有索引:創建額外的文件,以某種格式存儲
索引種類: hash 無序 單值查找快 範圍查找慢
btree 數據結構: 二叉樹
30

10 40

5 15 35 66

1 6 11 19 21 39 55 100

相關命令: desc t1 查看表結構
show create table t1\G 顯示創建表時的sql語句 將表格90度旋轉
show index from t1 查看索引
explain sql語句 查看預估的執行時間

set profiling = 1; 查看執行時間
SQL...
show profiles;
建立索引:
a 額外的文件保存特殊的數據結構
b 查詢快 插入更新刪除慢
c 命中索引
select * from t1 where email=‘fejfef‘
select * from t1 where email like ‘fdjafh‘; 慢
創建普通索引:
create index 索引名稱 on 表名(列名)
drop index 索引名稱 on 表名
創建唯一索引:
create unique index 索引名稱 on 表名(列名)
drop unique index 索引名稱 on 表名
創建組合索引:
- create unique index 索引名稱 on 表名(列名,列名)
- drop unique index 索引名稱 on 表名

- create index ix_name_email on userinfo3(name,email,)
最左前綴匹配
select * from userinfo3 where name=‘alex‘; 匹配
select * from userinfo3 where name=‘alex‘ and email=‘asdf‘; 匹配

select * from userinfo3 where [email protected]; 不匹配,不會按照索引查找


覆蓋索引: 只是一種行為
直接在索引文件中就可以找到的數據
索引合並: 只是一種行為
把多個單列索引合並使用

組合索引效率 > 索引合並效率
組合索引
- (name,email,) 適用於經常使用聯合查找的情況
select * from userinfo3 where name=‘alex‘ and email=‘asdf‘;
select * from userinfo3 where name=‘alex‘;
索引合並:
- name
- email
select * from userinfo3 where name=‘alex‘ and email=‘asdf‘;
select * from userinfo3 where name=‘alex‘;
select * from userinfo3 where email=‘alex‘;


正確使用索引
1 like
select * from t1 where email=‘fejfef‘
select * from t1 where email like ‘fdjafh‘; 慢
2 函數
count(1)或count(列) 代替 count(*)
select * from tb1 where reverse(name) = ‘wupeiqi‘;
3 or
nid 建立索引而email沒有建立索引---------不會按照索引查找
select * from tb1 where nid = 1 or email = [email protected];

nid建立索引,email沒有建立索引,name也建立索引,-----會按照索引查找
select * from tb1 where nid = 1 or email = [email protected] and name = ‘alex‘
4 類型不一致
如果列是字符串類型,傳入條件是必須用引號引起來
select * from tb1 where name = 999; 不會走索引
select * from tb1 where name = ‘999‘; 會走索引
5 !=
select * from tb1 where name != ‘alex‘
特別的:如果是主鍵,則還是會走索引
select * from tb1 where nid != 123
6 - >
select * from tb1 where name > ‘alex‘
特別的:如果是主鍵或索引是整數類型,則還是會走索引
select * from tb1 where nid > 123
select * from tb1 where num > 123
7 order by
當根據索引排序時候,選擇的映射如果不是索引,則不走索引
特別的:如果對主鍵排序,則還是走索引:
select * from tb1 order by nid desc;
8 組合索引最左前綴

其他註意事項
避免使用 select *
count(1)或count(列) 代替count(*)
創建表時盡量用char代替varchar
表的字段順序按照固定長度的字段優先
組合索引代替多個單列索引(經常使用多個條件查詢時)
盡量使用短索引 create index xxxx on userinfo(username(3)) 對username的前3個字符建立索引
連表時註意條件類型需一致
索引散列值不適合建索引
limit 分頁
1 select * from userinfo4 limit 20,10
2 select * from userinfo3 where id in(select id from userinfo3 limit 200000,10)
3 方案:記錄當前頁最大或最小ID
1 頁面只有上一頁和下一頁
下一頁:select * from userinfo3 where id > max_id limit 10;
下一頁:select * from userinfo3 where id < min_id order by id desc limit 10;
2 上一頁 192 193 [196] 197 198 199 下一頁
select * from userinfo4 where id in(
select id from (select id from userinfo4 where id > max_id limit 30) as N order by N.id desc limit 10)
4 select * from userinfo4 where id between 1 in 10 錯誤,因為id不連續,無法使用範圍查找


查詢時間:explain + 查詢SQL - 用於顯示SQL執行信息參數,根據參考信息可以進行SQL優化
執行計劃:讓mysql預估執行操作所需要的時間(一般正確)

all < index < range <index_merge < ref_or_null < ref <eq_ref <system/const
慢:select * from userinfo3 where name=‘alex‘

explain select * from userinfo3 where name=‘alex‘
type : all(全表掃描)
select * from userinfo3 limit 1; (特殊情況)
快:
select * from userinfo3 where email=‘alex‘
type:const(走索引)


DBA工作:
慢日誌:--執行時間
--未命中索引
--日誌文件路徑
配置:
--內存
show variables like ‘%query%‘
set global 變量名 = 值
--配置文件
slow_query_log = OFF 是否開啟慢日誌記錄
long_query_time = 2 時間限制,超過此時間,則記錄
slow_query_log_file = /usr/slow.log 日誌文件
log_queries_not_using_indexes = OFF 為使用索引的搜索是否記錄

修改:
1 mysqld--default-file=‘F:\mysql-5.7.16-winx64\my-default.ini‘

2 my.conf內容:
slow_query_log=ON
slow_query_log_file=‘........‘
註意:修改配置文件之後,需要重啟服務

--查看慢日誌:
mysqldumpslow -s at -a /usr/slow.log
-s ORDER 排序方式
what to sort by (al, at, ar, c, l, r, t), ‘at‘ is default
al: average lock time
ar: average rows sent
at: average query time
c: count
l: lock time
r: rows sent
t: query time
-a 不要將SQL中數字轉換成N,字符串轉換成S。don‘t abstract all numbers to N and strings to ‘S‘

mysql基礎(四)之索引