sql索引有什么用,mysql索引原理及用法

 2023-11-05 阅读 28 评论 0

摘要:MySQL索引原理及慢查詢優化Mysql explain用法和性能分析MySQL 索引優化全攻略 1.索引作用 在索引列上,除了上面提到的有序查找之外,數據庫利用各種各樣的快速定位技術,能夠大大提高查詢效率。特別是當數據量非常大,查詢涉及多個表時ÿ

MySQL索引原理及慢查詢優化
Mysql explain用法和性能分析
MySQL 索引優化全攻略


1.索引作用

在索引列上,除了上面提到的有序查找之外,數據庫利用各種各樣的快速定位技術,能夠大大提高查詢效率。特別是當數據量非常大,查詢涉及多個表時,使用索引往往能使查詢速度加快成千上萬倍。

例如,有3個未索引的表t1、t2、t3,分別只包含列c1、c2、c3,每個表分別含有1000行數據組成,指為1~1000的數值,查找對應值相等行的查詢如下所示。

sql索引有什么用。SELECT c1,c2,c3 FROM t1,t2,t3 WHERE c1=c2 AND c1=c3

此查詢結果應該為1000行,每行包含3個相等的值。在無索引的情況下處理此查詢,必須尋找3個表所有的組合,以便得出與WHERE子句相配的那些行。而可能的組合數目為1000×1000×1000(十億),顯然查詢將會非常慢。

如果對每個表進行索引,就能極大地加速查詢進程。利用索引的查詢處理如下。

(1)從表t1中選擇第一行,查看此行所包含的數據。

Mysql索引結構、(2)使用表t2上的索引,直接定位t2中與t1的值匹配的行。類似,利用表t3上的索引,直接定位t3中與來自t1的值匹配的行。

(3)掃描表t1的下一行并重復前面的過程,直到遍歷t1中所有的行。

在此情形下,仍然對表t1執行了一個完全掃描,但能夠在表t2和t3上進行索引查找直接取出這些表中的行,比未用索引時要快一百萬倍。

利用索引,MySQL加速了WHERE子句滿足條件行的搜索,而在多表連接查詢時,在執行連接時加快了與其他表中的行匹配的速度。

2. 創建索引

索引sql。在執行CREATE TABLE語句時可以創建索引,也可以單獨用CREATE INDEX或ALTER TABLE來為表增加索引。

ALTER TABLE

ALTER TABLE用來創建普通索引、UNIQUE索引或PRIMARY KEY索引。

ALTER TABLE table_name ADD INDEX index_name (column_list)

mysql索引失效?ALTER TABLE table_name ADD UNIQUE (column_list)

ALTER TABLE table_name ADD PRIMARY KEY (column_list)

其中table_name是要增加索引的表名,column_list指出對哪些列進行索引,多列時各列之間用逗號分隔。索引名index_name可選,缺省時,MySQL將根據第一個索引列賦一個名稱。另外,ALTER TABLE允許在單個語句中更改多個表,因此可以在同時創建多個索引。

CREATE INDEX

mysql索引優化?CREATE INDEX可對表增加普通索引或UNIQUE索引。

CREATE INDEX index_name ON table_name (column_list)

CREATE UNIQUE INDEX index_name ON table_name (column_list)

table_name、index_name和column_list具有與ALTER TABLE語句中相同的含義,索引名不可選。另外,不能用CREATE INDEX語句創建PRIMARY KEY索引。

3.索引類型

mysql8?在創建索引時,可以規定索引能否包含重復值。如果不包含,則索引應該創建為PRIMARY KEY或UNIQUE索引。對于單列惟一性索引,這保證單列不包含重復的值。對于多列惟一性索引,保證多個值的組合不重復。

PRIMARY KEY索引和UNIQUE索引非常類似。事實上,PRIMARY KEY索引僅是一個具有名稱PRIMARY的UNIQUE索引。這表示一個表只能包含一個PRIMARY KEY,因為一個表中不可能具有兩個同名的索引。

下面的SQL語句對students表在sid上添加PRIMARY KEY索引。

ALTER TABLE students ADD PRIMARY KEY (sid)

4. 刪除索引

mysql,可利用ALTER TABLE或DROP INDEX語句來刪除索引。類似于CREATE INDEX語句,DROP INDEX可以在ALTER TABLE內部作為一條語句處理,語法如下。

DROP INDEX index_name ON talbe_name

ALTER TABLE table_name DROP INDEX index_name

ALTER TABLE table_name DROP PRIMARY KEY

mysql聯合索引原理,其中,前兩條語句是等價的,刪除掉table_name中的索引index_name。

第3條語句只在刪除PRIMARY KEY索引時使用,因為一個表只可能有一個PRIMARY KEY索引,因此不需要指定索引名。如果沒有創建PRIMARY KEY索引,但表具有一個或多個UNIQUE索引,則MySQL將刪除第一個UNIQUE索引。

如果從表中刪除了某列,則索引會受到影響。對于多列組合的索引,如果刪除其中的某列,則該列也會從索引中刪除。如果刪除組成索引的所有列,則整個索引將被刪除。

5.查看索引

mysql> show index from tblname;

mysql函數索引,mysql> show keys from tblname;

· Table

表的名稱。

· Non_unique

mysql索引原理面試。如果索引不能包括重復詞,則為0。如果可以,則為1。

· Key_name

索引的名稱。

· Seq_in_index

索引中的列序列號,從1開始。

· Column_name

列名稱。

· Collation

列以什么方式存儲在索引中。在MySQL中,有值‘A’(升序)或NULL(無分類)。

· Cardinality

索引中唯一值的數目的估計值。通過運行ANALYZE TABLE或myisamchk -a可以更新。基數根據被存儲為整數的統計數據來計數,所以即使對于小型表,該值也沒有必要是精確的。基數越大,當進行聯合時,MySQL使用該索引的機會就越大。

· Sub_part

如果列只是被部分地編入索引,則為被編入索引的字符的數目。如果整列被編入索引,則為NULL。

· Packed

指示關鍵字如何被壓縮。如果沒有被壓縮,則為NULL。

· Null

如果列含有NULL,則含有YES。如果沒有,則該列含有NO。

· Index_type

用過的索引方法(BTREE, FULLTEXT, HASH, RTREE)。

· Comment

EXPLAIN列的解釋:
table:顯示這一行的數據是關于哪張表的
type:這是重要的列,顯示連接使用了何種類型。從最好到最差的連接類型為const、eq_reg、ref、range、indexhe和ALL
possible_keys:顯示可能應用在這張表中的索引。如果為空,沒有可能的索引。可以為相關的域從WHERE語句中選擇一個合適的語句
key: 實際使用的索引。如果為NULL,則沒有使用索引。很少的情況下,MYSQL會選擇優化不足的索引。這種情況下,可以在SELECT語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引
key_len:使用的索引的長度。在不損失精確性的情況下,長度越短越好
ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數
rows:MYSQL認為必須檢查的用來返回請求數據的行數
Extra:關于MYSQL如何解析查詢的額外信息。將在表4.3中討論,但這里可以看到的壞的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,結果是檢索會很慢
extra列返回的描述的意義
Distinct:一旦MYSQL找到了與行相聯合匹配的行,就不再搜索了
Not exists: MYSQL優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行,就不再搜索了
Range checked for each Record(index map:#):沒有找到理想的索引,因此對于從前面表中來的每一個行組合,MYSQL檢查使用哪個索引,并用它來從表中返回行。這是使用索引的最慢的連接之一
Using filesort: 看到這個的時候,查詢就需要優化了。MYSQL需要進行額外的步驟來發現如何對返回的行排序。它根據連接類型以及存儲排序鍵值和匹配條件的全部行的行指針來排序全部行
Using index: 列數據是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,這發生在對表的全部的請求列都是同一個索引的部分的時候
Using temporary 看到這個的時候,查詢需要優化了。這里,MYSQL需要創建一個臨時表來存儲結果,這通常發生在對不同的列集進行ORDER BY上,而不是GROUP BY上
Where used 使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。如果不想返回表中的全部行,并且連接類型ALL或index,這就會發生,或者是查詢有問題不同連接類型的解釋(按照效率高低的順序排序)
system 表只有一行:system表。這是const連接類型的特殊情況
const:表中的一個記錄的最大值能夠匹配這個查詢(索引可以是主鍵或惟一索引)。因為只有一行,這個值實際就是常數,因為MYSQL先讀這個值然后把它當做常數來對待
eq_ref:在連接中,MYSQL在查詢時,從前面的表中,對每一個記錄的聯合都從表中讀取一個記錄,它在查詢使用了索引為主鍵或惟一鍵的全部時使用
ref:這個連接類型只有在查詢使用了不是惟一或主鍵的鍵或者是這些類型的部分(比如,利用最左邊前綴)時發生。對于之前的表的每一個行聯合,全部記錄都將從表中讀出。這個類型嚴重依賴于根據索引匹配的記錄多少—越少越好
range:這個連接類型使用索引返回一個范圍中的行,比如使用>或<查找東西時發生的情況
index: 這個連接類型對前面的表中的每一個記錄聯合進行完全掃描(比ALL更好,因為索引一般小于表數據)
ALL:這個連接類型對于前面的每一個記錄聯合進行完全掃描,這一般比較糟糕,應該盡量避免
其中,
type=const 表示通過索引一次就找到了,
key=primary 表示使用了主鍵
type=all, 表示為全表掃描,
key=null 表示沒用到索引;
type=ref, 因為這時認為是多個匹配行,在聯合查詢中,一般為REF
2 MYSQL中的組合索引
假設表有id,key1,key2,key3,把三者形成一個組合索引,則
如:
where key1=….
where key1=1 and key2=2
where key1=3 and key3=3 and key2=2
根據最左原則,這些都是可以使用索引的哦

from test where key1=1 order by key3
用explain分析的話,只用到了normal_key索引,但只對where子句起作用,而后面的order by需要排序
3 使用慢查詢分析:
在my.ini中:
long_query_time=1
log-slow-queries=d:\mysql5\logs\mysqlslow.log
把超過1秒的記錄在慢查詢日志中
可以用mysqlsla來分析之。也可以在mysqlreport中,有如
DMS 分別分析了select ,update,insert,delete,replace等所占的百份比
4 MYISAM和INNODB的鎖定
myisam中,注意是表鎖來的,比如在多個UPDATE操作后,再SELECT時,會發現SELECT操作被鎖定了,必須等所有UPDATE操作完畢后,再能SELECT
innodb的話則不同了,用的是行鎖,不存在上面問題。
5 MYSQL的事務配置項
innodb_flush_log_at_trx_commit=1
表示事務提交時立即把事務日志寫入磁盤,同時數據和索引也更新
innodb_flush_log_at_trx_commit=0
事務提交時,不立即把事務日志寫入磁盤,每隔1秒寫一次
innodb_flush_log_at_trx_commit=2
事務提交時,立即寫入磁盤文件(這里只是寫入到內核緩沖區,但不立即刷新到磁盤,而是每隔1秒刷新到盤,同時更新數據和索引
explain用法
EXPLAIN tbl_name
或:
EXPLAIN [EXTENDED] SELECT select_options
前者可以得出一個表的字段結構等等,后者主要是給出相關的一些索引信息,而今天要講述的重點是后者。
舉例
mysql> explain select * from event;
+—-+————-+——-+——+—————+——+———+——+——+——-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+——-+——+—————+——+———+——+——+——-+
| 1 | SIMPLE | event | ALL | NULL | NULL | NULL | NULL | 13 | |
+—-+————-+——-+——+—————+——+———+——+——+——-+
1 row in set (0.00 sec)
各個屬性的含義
id
select查詢的序列號
select_type
select查詢的類型,主要是區別普通查詢和聯合查詢、子查詢之類的復雜查詢。
table
輸出的行所引用的表。
type
聯合查詢所使用的類型。
type顯示的是訪問類型,是較為重要的一個指標,結果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般來說,得保證查詢至少達到range級別,最好能達到ref。
possible_keys
指出MySQL能使用哪個索引在該表中找到行。如果是空的,沒有相關的索引。這時要提高性能,可通過檢驗WHERE子句,看是否引用某些字段,或者檢查字段不是適合索引。
key
顯示MySQL實際決定使用的鍵。如果沒有索引被選擇,鍵是NULL。
key_len
顯示MySQL決定使用的鍵長度。如果鍵是NULL,長度就是NULL。文檔提示特別注意這個值可以得出一個多重主鍵里mysql實際使用了哪一部分。
ref
顯示哪個字段或常數與key一起被使用。
rows
這個數表示mysql要遍歷多少數據才能找到,在innodb上是不準確的。
Extra
如果是Only index,這意味著信息只用索引樹中的信息檢索出的,這比掃描整個表要快。
如果是where used,就是使用上了where限制。
如果是impossible where 表示用不著where,一般就是沒查出來啥。
如果此信息顯示Using filesort或者Using temporary的話會很吃力,WHERE和ORDER BY的索引經常無法兼顧,如果按照WHERE來確定索引,那么在ORDER BY時,就必然會引起Using filesort,這就要看是先過濾再排序劃算,還是先排序再過濾劃算。
常見的一些名詞解釋
Using filesort
MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。
Using index
從只使用索引樹中的信息而不需要進一步搜索讀取實際的行來檢索表中的列信息。
Using temporary
為了解決查詢,MySQL需要創建一個臨時表來容納結果。
ref
對于每個來自于前面的表的行組合,所有有匹配索引值的行將從這張表中讀取
ALL
完全沒有索引的情況,性能非常地差勁。
index
與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引文件通常比數據文件小。
SIMPLE
簡單SELECT(不使用UNION或子查詢)

轉載于:https://www.cnblogs.com/jonky/p/10155401.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/166216.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息