如何使用索引提高查詢速度
使用索引提高查詢速度
1.前言
在web開發(fā)中,頁面模板,業(yè)務(wù)邏輯(包括緩存、連接池)和數(shù)據(jù)庫這三個(gè)部分,數(shù)據(jù)庫在其中負(fù)責(zé)執(zhí)行SQL查詢并返回查詢結(jié)果,是影響網(wǎng)站速度最重要的性能瓶頸。本文主要針對(duì)MySql數(shù)據(jù)庫,雙十一的電商大戰(zhàn),引發(fā)了淘寶技術(shù)熱議,而淘寶現(xiàn)在去IOE(I代表IBM的縮寫,即去IBM的存儲(chǔ)設(shè)備和小型機(jī);O是代表Oracle的縮寫,也即去Oracle數(shù)據(jù)庫,采用MySQL和Hadoop替代的解決方案,;E是代表EMC2,即去EMC2的設(shè)備性,用PC Server替代EMC2),大量采用MySql集群!讓MySql再次成為耀眼的明星!而優(yōu)化數(shù)據(jù)的重要一步就是索引的建立,對(duì)于mysql中出現(xiàn)的慢查詢,我們可以通過使用索引來提升查詢速度。索引用于快速找出在某個(gè)列中有一特定值的行。不使用索引,MySQL將進(jìn)行全表掃描,從第1條記錄開始然后讀完整個(gè)表直到找出相關(guān)的行。
2.mysql索引類型及創(chuàng)建
常用的索引類型有
(1)主鍵索引
它是一種特殊的唯一索引,不允許有空值。一般是在建表的時(shí)候同時(shí)創(chuàng)建主鍵索引:
CREATE TABLE user(
id int unsigned not null auto_increment,
name varchar(50) not null,
email varchar(40) not null,
primary key (id)
);
(2)普通索引
這是最基本的索引,它沒有任何限制。創(chuàng)建方式:
create index idx_name on user(
name(20)
);
mysql支持前綴索引,一般姓名不會(huì)超過20個(gè)字符,所以我們這里建立索引的時(shí)候限定了長度20,這樣可以節(jié)省索引文件大小
(3)唯一索引
它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。創(chuàng)建方式:
CREATE UNIQUE INDEX idx_email ON user(
);
(4)全文索引
MySQL支持全文索引和搜索功能。MySQL中的全文索引類型為FULLTEXT的索引。 FULLTEXT 索引僅可用于 MyISAM表;
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
);
mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database');
查詢結(jié)果:
+----+-------------------+------------------------------------------+
| id | title | body |
+----+-------------------+------------------------------------------+
| 5 | MySQL vs. YourSQL | In the following database comparison ... |
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
+----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)
MATCH()函數(shù)對(duì)于一個(gè)字符串執(zhí)行資料庫內(nèi)的自然語言搜索。一個(gè)資料庫就是1套1個(gè)或2個(gè)包含在FULLTEXT內(nèi)的列。搜索字符串作為對(duì)AGAINST()的參數(shù)而被給定。對(duì)于表中的每一行, MATCH() 返回一個(gè)相關(guān)值,即, 搜索字符串和 MATCH()表中指定列中該行文字之間的一個(gè)相似性度量。
(5)復(fù)合索引
CREATE TABLE test (
id INT NOT NULL,
last_name CHAR(30) NOT NULL,
first_name CHAR(30) NOT NULL,
PRIMARY KEY (id),
INDEX name (last_name,first_name)
);
name索引是一個(gè)對(duì)last_name和first_name的索引。索引可以用于為last_name,或者為last_name和first_name在已知范圍內(nèi)指定值的查詢。因此,name索引用于下面的查詢:
SELECT * FROM test WHERE last_name='Widenius';
SELECT * FROM test WHERE last_name='Widenius' AND first_name='Michael';
但是不能用于SELECT * FROM test WHERE first_name='Michael';這是因?yàn)镸ySQL組合索引為“最左前綴”的結(jié)果,簡(jiǎn)單的理解就是只從最左面的開始組合。
3.在什么情況下使用索引
(1)為搜索字段建索引,如果在你的表中,某個(gè)字段你經(jīng)常用來做搜索,那么,請(qǐng)為其建立索引吧。一般來說,在WHERE和JOIN中出現(xiàn)的列需要建立索引以提高查詢速度。
例如從fps表(表中有name字段)中檢索姓名為"李武"的人,
下面用explain來解釋執(zhí)行建立索引和未建立索引的區(qū)別:
a.未建立索引前
explain select name from fps where name="李武";

[SQL] select name from fps where name="李武";
影響的數(shù)據(jù)欄: 0
時(shí)間: 0.003ms
b.建立索引后
create index idx_name on fps(
name
);
explain select name from fps where name="李武";

[SQL] select name from fps where name="李武";
影響的數(shù)據(jù)欄: 0
時(shí)間: 0.001ms
(2)下面我們就來看看這個(gè)EXPLAIN分析結(jié)果的含義。
table:這是表的名字。
type:連接操作的類型。下面是MySQL文檔關(guān)于ref連接類型的說明:
“對(duì)于每個(gè)來自于前面的表的行組合,所有有匹配索引值的行將從這張表中讀取。如果聯(lián)接只使用鍵的最左邊的前綴,或如果鍵不是
UNIQUE或PRIMARY KEY(換句話說,如果聯(lián)接不能基于關(guān)鍵字選擇單個(gè)行的話),則使用ref。如果使用的鍵僅僅匹配少量行,該聯(lián)接
類型是不錯(cuò)的?!?在本例中,由于索引不是UNIQUE類型,ref是我們能夠得到的最好連接類型。 如果EXPLAIN顯示連接類型是“ALL”,而且你并不想從表里面選擇出大多數(shù)記錄,那么MySQL的操作效率將非常低,因?yàn)樗獟呙枵麄€(gè)表。你可以加入更多的索引來解決這個(gè)問題。預(yù)知更多信息,請(qǐng)參見MySQL的手冊(cè)說明。
possible_keys:
可能可以利用的索引的名字。這里的索引名字是創(chuàng)建索引時(shí)指定的索引昵稱;如果索引沒有昵稱,則默認(rèn)顯示的是索引中第一個(gè)列的名字
(在本例中,它是“idx_name”)。
Key:
它顯示了MySQL實(shí)際使用的索引的名字。如果它為空(或NULL),則MySQL不使用索引。
key_len:
索引中被使用部分的長度,以字節(jié)計(jì)。
ref:
它顯示的是列的名字(或單詞“const”),MySQL將根據(jù)這些列來選擇行。在本例中,MySQL根據(jù)三個(gè)常量選擇行。
rows:
MySQL所認(rèn)為的它在找到正確的結(jié)果之前必須掃描的記錄數(shù)。顯然,這里最理想的數(shù)字就是1。 本例中未索引前遍歷的記錄數(shù)為1041,而建立索引后為1
Extra:
這里可能出現(xiàn)許多不同的選項(xiàng),其中大多數(shù)將對(duì)查詢產(chǎn)生負(fù)面影響。在本例中,MySQL只是提醒我們它將用using where,using index子句限制搜索結(jié)果集。
4.最常用的存儲(chǔ)引擎:
(1)Myisam存儲(chǔ)引擎:每個(gè)Myisam在磁盤上存儲(chǔ)成三個(gè)文件。文件名都和表名相同,擴(kuò)展名分別為.frm(存儲(chǔ)表定義)、.MYD(存儲(chǔ)數(shù)據(jù))、.MYI(存儲(chǔ)索引)。數(shù)據(jù)文件和索引文件可以放置在不同目錄,平均分布io,獲得更快的速度。對(duì)存儲(chǔ)大小沒有限制,MySQL數(shù)據(jù)庫的最大有效表尺寸通常是由操作系統(tǒng)對(duì)文件大小的限制決定的,
(2)InnoDB存儲(chǔ)引擎:具有提交、回滾、奔潰恢復(fù)能力的事務(wù)安全。與Myisam相比,InnoDB的寫效率差一些并且會(huì)占用更多的磁盤空間以保留數(shù)據(jù)和索引。
(3)如何選擇合適的引擎
下面是常用存儲(chǔ)引擎適用的環(huán)境:
Myisam:它是在Web、數(shù)據(jù)倉儲(chǔ)和其他應(yīng)用環(huán)境下最常使用的存儲(chǔ)引擎;
InnoDB:用于事務(wù)處理應(yīng)用程序,具有更多特性,包括ACID事務(wù)特性。
- 批量處理JDBC語句提高處理速度
- 如何提高M(jìn)YSQL數(shù)據(jù)庫的查詢統(tǒng)計(jì)速度 select 索引應(yīng)用
- 提高頁面加載速度的幾個(gè)方法小結(jié)
- php 處理上百萬條的數(shù)據(jù)庫如何提高處理查詢速度
- 啟用IIS6的GZIP功能,提高網(wǎng)站打開速度,減少帶寬占用
- js 利用image對(duì)象實(shí)現(xiàn)圖片的預(yù)加載提高訪問速度
- ANT 壓縮(去掉空格/注釋)JS文件可提高js運(yùn)行速度
- 利用JS延遲加載百度分享代碼,提高網(wǎng)頁速度
- 延時(shí)加載JavaScript代碼提高速度
相關(guān)文章
MySQL復(fù)制表結(jié)構(gòu)和內(nèi)容到另一張表中的SQL語句
這篇文章主要介紹了MySQL復(fù)制表結(jié)構(gòu)和內(nèi)容到另一張表中的SQL語句,需要的朋友可以參考下2014-07-07Mysql中STR_TO_DATE函數(shù)使用(字符串轉(zhuǎn)為日期/時(shí)間值)
這篇文章主要給大家介紹了關(guān)于Mysql中STR_TO_DATE函數(shù)使用的相關(guān)資料,STR_TO_DATE函數(shù)的主要功能是字符串轉(zhuǎn)為日期/時(shí)間值,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09基于MySQL數(shù)據(jù)庫的數(shù)據(jù)約束實(shí)例及五種完整性約束介紹
今天小編就為大家分享一篇關(guān)于基于MySQL數(shù)據(jù)庫的數(shù)據(jù)約束實(shí)例及五種完整性約束介紹,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01MySQL創(chuàng)建數(shù)據(jù)庫和創(chuàng)建數(shù)據(jù)表
MySQL?是最常用的數(shù)據(jù)庫,在數(shù)據(jù)庫操作中,基本都是增刪改查操作,簡(jiǎn)稱CRUD。但是,這篇文章主要介紹了數(shù)據(jù)庫和數(shù)據(jù)表如何創(chuàng)建,想詳細(xì)了解的小伙伴可以參考閱讀一下2023-03-03深入了解MySQL中分區(qū)表的原理與企業(yè)級(jí)實(shí)戰(zhàn)
本文詳細(xì)講解什么是分區(qū)表,分區(qū)表增刪改查的工作原理以及分區(qū)表的實(shí)戰(zhàn),分區(qū)表的場(chǎng)景有哪些,哪些場(chǎng)景不建議用分區(qū)表,并列舉出六點(diǎn)使用分區(qū)表的誤區(qū),需要的可以參考一下2022-11-11