如何快速上手mysql_mysql快速上手3
上一章給大家說(shuō)的是數(shù)據(jù)庫(kù)的視圖,存儲(chǔ)過(guò)程等等操作,這章主要講索引,以及索引注意事項(xiàng),如果想看前面的文章,url如下:
索引簡(jiǎn)介
索引是對(duì)數(shù)據(jù)庫(kù)表中一個(gè)或多個(gè)列(例如,employee 表的姓名 (name) 列)的值進(jìn)行排序的結(jié)構(gòu)。如果想按特定職員的姓來(lái)查找他或她,則與在表中搜索所有的行相比,索引有助于更快地獲取信息。
例如這樣一個(gè)查詢:select * from table1 where id=10000。如果沒(méi)有索引,必須遍歷整個(gè)表,直到ID等于10000的這一行被找到為止;有了索引之后(必須是在ID這一列上建立的索引),即可在索引中查找。由于索引是經(jīng)過(guò)某種算法優(yōu)化過(guò)的,因而查找次數(shù)要少的多。可見(jiàn),索引插敘的速度要比沒(méi)有索引的速度要快很多
MySQL中常見(jiàn)索引有:
普通索引
唯一索引
主鍵索引
組合索引
下面就應(yīng)用一下索引吧
索引操作
一、普通索引(index)
普通所以只有一個(gè)功能,就是加快查找速度。操作如下
1、先創(chuàng)建一個(gè)表
create table tab1(
nid int not nullauto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
extra text,
index ix_name (name)
)
2、創(chuàng)建索引
create index 索引名稱 on 表名(列名)
3、刪除索引
drop 索引名稱 on 表名;
4、查看索引
show index from 表名;
5、注意事項(xiàng)(對(duì)于創(chuàng)建索引時(shí)如果是BLOB?和?TEXT?類型,必須指定length。)
create index index_name on tab1(extra(32));
二、唯一索引(unique)
唯一性索引unique index和一般索引normal index最大的差異就是在索引列上增加了一層唯一約束。添加唯一性索引的數(shù)據(jù)列可以為空,但是只要存在數(shù)據(jù)值,就必須是唯一的。
1、創(chuàng)建表+唯一索引
create table tab2(
nid int not nullauto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
extra text,
unique ix_name (name) --重點(diǎn)在這里
)
2、創(chuàng)建索引
create unique index 索引名 on 表名(列名)
3、刪除索引
drop unique index 索引名 on 表名
三、主鍵索引
在數(shù)據(jù)庫(kù)關(guān)系圖中為表定義一個(gè)主鍵將自動(dòng)創(chuàng)建主鍵索引,主鍵索引是唯一索引的特殊類型。主鍵索引要求主鍵中的每個(gè)值是唯一的。當(dāng)在查詢中使用主鍵索引時(shí),它還允許快速訪問(wèn)數(shù)據(jù)。數(shù)據(jù)不能為空
1、創(chuàng)建表+主鍵索引
create table in1(
nid int not nullauto_increment,
name varchar(32) not null,
email varchar(64) not null,
extra text,
primary key(nid),
index zhang (name)
)
2、創(chuàng)建主鍵
alter table 表名 add primary key(列名);
3、刪除主鍵
alter table 表名 drop primary key;
alter table 表名 modify 列名 int, drop primary key;
四、組合索引
組合索引,就是組合查詢的意思嘛嘻嘻,將兩列或者多列組合成一個(gè)索引進(jìn)行查詢
其應(yīng)用場(chǎng)景為:頻繁的同時(shí)使用n列來(lái)進(jìn)行查詢,如:where name = '張巖林' and email = 666。
1、創(chuàng)建表
create table in3(
nid int not nullauto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
extra text
)
2、創(chuàng)建組合索引
create index ix_name_email on in3(name,email);
如上創(chuàng)建組合索引之后,查詢有的會(huì)使用索引,有的不會(huì):
name and email ?-- 使用索引
name ? ? ? ? ? ? ? ? -- 使用索引
email ? ? ? ? ? ? ? ? -- 不使用索引
索引注意事項(xiàng)
1、正確使用索引
數(shù)據(jù)庫(kù)表中添加索引后能夠讓查詢數(shù)據(jù)庫(kù)速度飛快,但前提必須是正確的使用索引來(lái)查詢,如果以錯(cuò)誤的方式使用,則即使建立索引也會(huì)不奏效。
下面這些情況不會(huì)使用到索引:
1、like '%xx'
select * from tb1 where name like '%cn';
2、使用函數(shù)
select * from tb1 where reverse(name) = '張巖林';
3、or
select * from tb1 where nid = 1 or email='zhangyanlin@live.com';
特別的:當(dāng)or條件中有未建立索引的列才失效,以下會(huì)走索引
select * from tb1 where nid = 1 or name = 'zhangyanlin';
select * from tb1 where nid = 1 or email = 'zhangyanlin@live.com' and name = 'aylin'
4、類型不一致
如果列是字符串類型,傳入條件是必須用引號(hào)引起來(lái),不然...
select * from tb1 where name = 999;
5、 !=
select * from tb1 where name != 'aylin'特別的:如果是主鍵,則還是會(huì)走索引
select * from tb1 where nid != 123
6、 >
select * from tb1 where name > 'alex'特別的:如果是主鍵或索引是整數(shù)類型,則還是會(huì)走索引
select * from tb1 where nid > 123
select * from tb1 where num > 123
7、order by
select email fromtb1 order by name desc;
當(dāng)根據(jù)索引排序時(shí)候,選擇的映射如果不是索引,則不走索引
特別的:如果對(duì)主鍵排序,則還是走索引:
select * fromtb1 order by nid desc;
8、 組合索引最左前綴
如果組合索引為:(name,email)
name and email --使用索引
name --使用索引
email -- 不使用索引
2、其他注意事項(xiàng)
避免使用select?*
3、執(zhí)行計(jì)劃
explain + 查詢SQL - 用于顯示SQL執(zhí)行信息參數(shù),根據(jù)參考信息可以進(jìn)行SQL優(yōu)化
mysql> explain select * fromtb2;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | tb2 | ALL | NULL | NULL | NULL | NULL | 2 | NULL |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
id
查詢順序標(biāo)識(shí)
如:mysql> explain select * from (select nid,name from tb1 where nid < 10) asB;
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 9 | NULL |
| 2 | DERIVED | tb1 | range | PRIMARY | PRIMARY | 8 | NULL | 9 | Using where |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+特別的:如果使用union連接氣值可能為null
select_type
查詢類型
SIMPLE 簡(jiǎn)單查詢
PRIMARY 最外層查詢
SUBQUERY 映射為子查詢
DERIVED 子查詢
UNION 聯(lián)合
UNION RESULT 使用聯(lián)合的結(jié)果
...
table
正在訪問(wèn)的表名
type
查詢時(shí)的訪問(wèn)方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/constALL 全表掃描,對(duì)于數(shù)據(jù)表從頭到尾找一遍
select * fromtb1;
特別的:如果有l(wèi)imit限制,則找到之后就不在繼續(xù)向下掃描
select * from tb1 where email = 'seven@live.com'
select * from tb1 where email = 'seven@live.com' limit 1;
雖然上述兩個(gè)語(yǔ)句都會(huì)進(jìn)行全表掃描,第二句使用了limit,則找到一個(gè)后就不再繼續(xù)掃描。
INDEX 全索引掃描,對(duì)索引從頭到尾找一遍
select nid fromtb1;
RANGE 對(duì)索引列進(jìn)行范圍查找
select * from tb1 where name < 'alex';
PS:
between and
in
> >= < <=操作
注意:!= 和 >符號(hào)
INDEX_MERGE 合并索引,使用多個(gè)單列索引搜索
select * from tb1 where name = 'alex' or nid in (11,22,33);
REF 根據(jù)索引查找一個(gè)或多個(gè)值
select * from tb1 where name = 'seven';
EQ_REF 連接時(shí)使用primary key 或 unique類型
select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid =tb1.nid;
CONST 常量
表最多有一個(gè)匹配行,因?yàn)閮H有一行,在這行的列值可被優(yōu)化器剩余部分認(rèn)為是常數(shù),const表很快,因?yàn)樗鼈冎蛔x取一次。
select nid from tb1 where nid = 2;
SYSTEM 系統(tǒng)
表僅有一行(=系統(tǒng)表)。這是const聯(lián)接類型的一個(gè)特例。
select * from (select nid from tb1 where nid = 1) asA;
possible_keys
可能使用的索引
key
真實(shí)使用的
key_len
MySQL中使用索引字節(jié)長(zhǎng)度
rows
mysql估計(jì)為了找到所需的行而要讀取的行數(shù) ------只是預(yù)估值
extra
該列包含MySQL解決查詢的詳細(xì)信息
“Using index”
此值表示mysql將使用覆蓋索引,以避免訪問(wèn)表。不要把覆蓋索引和index訪問(wèn)類型弄混了。
“Using where”
這意味著mysql服務(wù)器將在存儲(chǔ)引擎檢索行后再進(jìn)行過(guò)濾,許多where條件里涉及索引中的列,當(dāng)(并且如果)它讀取索引時(shí),就能被存儲(chǔ)引擎檢驗(yàn),因此不是所有帶where子句的查詢都會(huì)顯示“Using where”。有時(shí)“Using where”的出現(xiàn)就是一個(gè)暗示:查詢可受益于不同的索引。
“Using temporary”
這意味著mysql在對(duì)查詢結(jié)果排序時(shí)會(huì)使用一個(gè)臨時(shí)表。
“Using filesort”
這意味著mysql會(huì)對(duì)結(jié)果使用一個(gè)外部索引排序,而不是按索引次序從表里讀取行。mysql有兩種文件排序算法,這兩種排序方式都可以在內(nèi)存或者磁盤上完成,explain不會(huì)告訴你mysql將使用哪一種文件排序,也不會(huì)告訴你排序會(huì)在內(nèi)存里還是磁盤上完成。
“Range checked foreach record(index map: N)”
這個(gè)意味著沒(méi)有好用的索引,新的索引將在聯(lián)接的每一行上重新估算,N是顯示在possible_keys列中索引的位圖,并且是冗余的。
4、limit分頁(yè)
分頁(yè)功能是個(gè)值得關(guān)注的問(wèn)題,因?yàn)槲覀儠?huì)一直用到
每頁(yè)顯示10條:
當(dāng)前 118 120, 125倒序:
大 小
980 970 7 6 6 5 54 43 32
21 19 98下一頁(yè):
select
*
fromtb1
wherenid < (select nid from (select nid from tb1 where nid < 當(dāng)前頁(yè)最小值 order by nid desc limit 每頁(yè)數(shù)據(jù) *【頁(yè)碼-當(dāng)前頁(yè)】) A order by A.nid asc limit 1)
order by
nid desc
limit 10;
select
*
fromtb1
wherenid < (select nid from (select nid from tb1 where nid < 970 order by nid desc limit 40) A order by A.nid asc limit 1)
order by
nid desc
limit 10;
上一頁(yè):
select
*
fromtb1
wherenid < (select nid from (select nid from tb1 where nid > 當(dāng)前頁(yè)最大值 order by nid asc limit 每頁(yè)數(shù)據(jù) *【當(dāng)前頁(yè)-頁(yè)碼】) A order by A.nid asc limit 1)
order by
nid desc
limit 10;
select
*
fromtb1
wherenid < (select nid from (select nid from tb1 where nid > 980 order by nid asc limit 20) A order by A.nid desc limit 1)
order by
nid desc
limit 10;
轉(zhuǎn)載:http://www.cnblogs.com/aylin/p/5777289.html
總結(jié)
以上是生活随笔為你收集整理的如何快速上手mysql_mysql快速上手3的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 手机屏幕厂家信息软件_警惕假个税手机软件
- 下一篇: 深入理解java虚拟机 - jvm高级特