MySQL索引的創建和使用


一、索引

索引是快速查詢的關鍵,MySQL索引的建立對於MySQL的高效運行是很重要的,對於較少的數據量,有沒有索引可能沒什么影響,但是當數據量較大時,查詢性能會急劇下降,特別是進行條件查詢的時候

二、索引的類型

  • 1、主鍵索引 PRIMARY KEY
    主鍵索引是一種特殊的唯一索引,它不允許有空值,一般在創建表的時候創建,而且一個表只能有一個主鍵
    創建表的時候創建主鍵
CREATE TABLE test(
id int(0) NOT NULL AUTO_INCREMENT,
hotelName varchar(255) DEFAULT NULL,
PRIMARY KEY('id')
);

使用ALTER命令添加主鍵

ALTER TABLE test ADD PRIMARY KEY('id');
  • 2、普通索引
    這是最基本的索引,沒有做任何限制
    創建表的時候指定
CREATE TABLE test(
id int(0) NOT NULL AUTO_INCREMENT,
hotelName varchar(255) DEFAULT NULL,
PRIMARY KEY('id'),
INDEX `hotelName`(`hotelName`)
);

使用ALTER命令添加普通索引

ALTER TABLE test ADD INDEX hotelName(hotelName)
  • 3、唯一索引 UNIQUE
    唯一索引列的值必須是唯一的,可以有空值,如果是組合索引,那么列值的組合必須是唯一的
    創建表的時候指定
CREATE TABLE test(
id int(0) NOT NULL AUTO_INCREMENT,
hotelName varchar(255) DEFAULT NULL,
PRIMARY KEY('id'),
UNIQUE INDEX `hotelName`(`hotelName`)
);

使用ALTER命令添加唯一索引

ALTER TABLE test ADD UNIQUE hotelName(hotelName)
  • 4、組合索引
    就是一個索引包含多個列
    使用ALTER命令添加添加組合索引
ALTER TABLE test ADD INDEX indexName(列1, 列2, 列3....)
  • 5、全文索引 FULLTEXT
    全文索引也是MyISAM的一個特殊索引類型,主要用於全文索引,InnoDB從Mysql5.6版本開始支持全文索引。
    創建表的時候指定
CREATE TABLE test(
id int(0) NOT NULL AUTO_INCREMENT,
hotelName varchar(255) DEFAULT NULL,
PRIMARY KEY('id'),
FULLTEXT INDEX `hotelName`(`hotelName`)
);

使用ALTER命令添加添加全文索引

ALTER TABLE test ADD FULLTEXT (hotelName)

三、創建索引的一般原則

  • 1、對於查詢頻率高的字段創建索引

索引的主要目的就是為了提升查詢的所讀,所以在查詢頻率高的字段上要創建索引

  • 2、對排序、分組、聯合查詢頻率高的字段創建索引

  • 3、索引的數量盡量要少,不要創建不必要的索引

沒創建一個索引都會占用相應的物理控件
過多的索引會導致insert、update、delete語句的執行效率降低

  • 4、如果需要將多列設置為索引時,可以采用多列索引

  • 5、選擇唯一性索引

唯一性索引的值時唯一的,可以更快速的通過該索引來確定某條記錄

  • 6、盡量使用數據量少的索引

如果索引的值很長,那么查詢速度會受到影響

  • 7、盡量使用前綴來索引

如果索引字段的值很長,最好使用值的前綴來索引

  • 8、刪除不在使用或者很少使用的索引

對於一些不經常使用的索引,應當及時的刪除,從而減少索引對更新操作的影響

四、執行計划 EXPLAIN

通過使用MySQL的執行計划來查看sql語句的執行效率,分析執行計划的各個顯示內容,找出查詢效率低的原因

EXPLAIN SELECT hotelID,c.city FROM hotelInfoApi as h, (SELECT city FROM hotelInfoApi GROUP BY city) as c WHERE h.city=c.city 

  • 執行計划的id
    select 查詢的序列號,表示執行的順序
  • id相同,執行順序由上至下
  • id不同,如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行
  • 執行計划的select_type
    查詢的類型,主要用於區分普通查詢、聯合查詢、子查詢等
  • SIMPLE:簡單的select查詢,查詢中不包含子查詢或者union
  • PRIMARY:查詢中包含子查詢,最外層查詢則被標記為primary
  • SUBQUERY/MATERIALIZED:SUBQUERY表示在select或where列表中包含了子查詢,MATERIALIZED:表示 where 后面 in 條件的子查詢
  • UNION:表示 union 中的第二個或后面的 select 語句
  • UNION RESULT: union的結果
  • DERIVED:派生表
  • 執行計划的table
    查詢涉及到的表
  • 直接顯示表名或者表的別名
  • <unionM,N> 由 ID 為 M,N 查詢 union 產生的結果
  • 由 ID 為 N 查詢產生的結果
  • 執行計划的type
    訪問類型, SQL查詢優化中的一個很重要的指標,結果值從好到壞依次是:system > const > eq_ref > ref > range > index > ALL。
  • system:系統表,少量數據,往往不需要進行磁盤IO
  • const:常量連接
  • eq_ref:主鍵索引(primary key)或者非空唯一索引(unique not null)等值掃描
  • ref:非主鍵非唯一索引等值掃描
  • range:范圍掃描
  • index:索引樹掃描
  • ALL:全表掃描(full table scan)
  • 執行計划possible_keys
    查詢過程中有可能用到的索引

  • 執行計划key
    實際使用的索引,如果為NULL,則沒有使用索引

  • 執行計划rows
    根據表統計信息或者索引選用情況,大致估算出找到所需的記錄所需讀取的行數

  • 執行計划filtered
    表示返回的行數需讀取行數的百分比,filtered的值越大越好.

  • 執行計划Extra
    額外信息

  • Using filesort:MySQL 對數據使用一個外部的文件內容進行了排序,而不是按照表內的索引進行排序讀取。
  • Using temporary:使用臨時表保存中間結果,也就是說 MySQL 在對查詢結果排序時使用了臨時表,常見於order by 或 group by。
  • Using index:表示 SQL 操作中使用了覆蓋索引(Covering Index),避免了訪問表的數據行,效率高。
  • Using index condition:表示 SQL 操作命中了索引,但不是所有的列數據都在索引樹上,還需要訪問實際的行記錄。
  • Using where:表示 SQL 操作使用了 where 過濾條件。
  • Select tables optimized away:基於索引優化 MIN/MAX 操作或者 MyISAM 存儲引擎優化 COUNT(*) 操作,不必等到執行階段再進行計算,查詢執行計划生成的階段即可完成優化。
  • Using join buffer(Block Nested Loop):表示 SQL 操作使用了關聯查詢或者子查詢,且需要進行嵌套循環計算。

五、慢查詢日志

MySQL的慢查詢日志是MySQL提供的一種日志記錄,它用來記錄在MySQL中響應時間超過閥值的語句,具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日志中。long_query_time的默認值為10,意思是運行10S以上的語句。默認情況下,MySQLl數據庫並不啟動慢查詢日志,需要我們手動來設置這個參數,當然,如果不是調優需要的話,一般不建議啟動該參數,因為開啟慢查詢日志會或多或少帶來一定的性能影響。慢查詢日志支持將日志記錄寫入文件,也支持將日志記錄寫入數據庫表。

  • 查看是否開啟慢查詢功能
show variables like 'slow_query%';
# slow_query_log 慢查詢開啟狀態
# slow_query_log_file 慢查詢日志存放的位置(這個目錄需要MySQL的運行帳號的可寫權限,一般設置為MySQL的數據存放目錄)

show variables like 'long_query_time';
# long_query_time 查詢超過多少秒才記錄

  • 開啟慢查詢
    臨時開啟
set global show_query_log='ON';
set global slow_query_log_file='/usr/local/var/mysql/192-slow.log';
set global long_query_time=2;

永久開啟,需要修改配置文件(mysql.cnf)

[mysqld]
slow_query_log = ON
slow_query_log_file = /usr/local/var/mysql/192-slow.log
long_query_time = 2

END


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM