十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
CREATE TABLE `test` ('aaa' varchar(16) NOT NULL default '', 'bbb' varchar(16) NOT NULL default '', 'ccc' int(11) UNSIGNED NOT NULL default 0, KEY `sindex` (`aaa`,`bbb`,`ccc`) ) ENGINE=MyISAM COMMENT='';\x0d\x0a\x0d\x0a這樣就在 aaa、bbb、ccc 3列上建立聯(lián)合索引了。\x0d\x0a\x0d\x0a如果表已經(jīng)建好了,那么就在phpmyadmin里面執(zhí)行:\x0d\x0aalert table test add INDEX `sindex` (`aaa`,`bbb`,`ccc`) \x0d\x0a\x0d\x0a就可以在這3列上建立聯(lián)合索引了。
十載的浦城網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。全網(wǎng)整合營銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整浦城建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)建站從事“浦城網(wǎng)站設(shè)計(jì)”,“浦城網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
MySQL的復(fù)合索引可以創(chuàng)建多個(gè),每個(gè)復(fù)合索引可以包含一列或多列。復(fù)合索引使用的基本原則是左側(cè)對(duì)齊原則。例如,復(fù)合索引包含A,B,C字段,實(shí)際相當(dāng)于創(chuàng)建了5個(gè)索引,即:
那么問題來了,如果我們創(chuàng)建兩個(gè)復(fù)合索引,復(fù)合索引1:包含A,B,C列和復(fù)合索引2:包含B,C列,MySQL如何執(zhí)行呢?
按照正常的邏輯,和復(fù)合索引的原則,應(yīng)該能命中的索引是A_B_C_index,讓我們拭目以待吧!
結(jié)果:和上次測(cè)試的不一致,這次雖然包含ABC三個(gè)列,但命中的索引是B_C_index
重要結(jié)論:當(dāng)命中兩個(gè)或者多個(gè)不同的復(fù)合索引時(shí),按照創(chuàng)建順序不同,MySQL會(huì)有不同策略來選取其中的一個(gè)復(fù)合索引。
在一個(gè)市民信息表上,是否有必要將身份證號(hào)
和名字建立聯(lián)合索引?
假設(shè)這個(gè)市民表的定義是這樣的:
CREATE TABLE `tuser` (
`id` int(11) NOT NULL,
`id_card` varchar(32) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`ismale` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `id_card` (`id_card`),
KEY `name_age` (`name`,`age`)
) ENGINE=InnoDB
我們知道,身份證號(hào)是市民的唯一標(biāo)識(shí)。也就是說,如果有根據(jù)身份證號(hào)查詢市民信息的需求,
我們只要在身份證號(hào)字段上建立索引就夠了。而再建立一個(gè)(身份證號(hào)、姓名)的聯(lián)合索引,是
不是浪費(fèi)空間?
如果現(xiàn)在有一個(gè)高頻請(qǐng)求,要根據(jù)市民的身份證號(hào)查詢他的姓名,這個(gè)聯(lián)合索引就有意義了。它
可以在這個(gè)高頻請(qǐng)求上用到覆蓋索引,不再需要回表查整行記錄,減少語句的執(zhí)行時(shí)間。
當(dāng)然,索引字段的維護(hù)總是有代價(jià)的。因此,在建立冗余索引來支持覆蓋索引時(shí)就需要權(quán)衡考慮
了。這正是業(yè)務(wù) DBA,或者稱為業(yè)務(wù)數(shù)據(jù)架構(gòu)師的工作。
最左前綴原則
看到這里你一定有一個(gè)疑問,如果為每一種查詢都設(shè)計(jì)一個(gè)索引,索引是不是太多了。如果我現(xiàn)
在要按照市民的身份證號(hào)去查他的家庭地址呢?雖然這個(gè)查詢需求在業(yè)務(wù)中出現(xiàn)的概率不高,但
總不能讓它走全表掃描吧?反過來說,單獨(dú)為一個(gè)不頻繁的請(qǐng)求創(chuàng)建一個(gè)(身份證號(hào),地址)的
索引又感覺有點(diǎn)浪費(fèi)。應(yīng)該怎么做呢?
這里,我先和你說結(jié)論吧。B+ 樹這種索引結(jié)構(gòu),可以利用索引的“最左前綴”,來定位記錄。
為了直觀地說明這個(gè)概念,我們用(name,age)這個(gè)聯(lián)合索引來分析。
? ? ? ? ? ? ? ? ?圖 2 (name,age)索引示意圖
可以看到,索引項(xiàng)是按照索引定義里面出現(xiàn)的字段順序排序的。
當(dāng)你的邏輯需求是查到所有名字是“張三”的人時(shí),可以快速定位到 ID4,然后向后遍歷得到所有
需要的結(jié)果。
如果你要查的是所有名字第一個(gè)字是“張”的人,你的 SQL 語句的條件是"where name like ‘張
%’"。這時(shí),你也能夠用上這個(gè)索引,查找到第一個(gè)符合條件的記錄是 ID3,然后向后遍歷,直
到不滿足條件為止。
可以看到,不只是索引的全部定義,只要滿足最左前綴,就可以利用索引來加速檢索。這個(gè)最左
前綴可以是聯(lián)合索引的最左 N 個(gè)字段,也可以是字符串索引的最左 M 個(gè)字符。
基于上面對(duì)最左前綴索引的說明,我們來討論一個(gè)問題:在建立聯(lián)合索引的時(shí)候,如何安排索引
內(nèi)的字段順序。
這里我們的評(píng)估標(biāo)準(zhǔn)是,索引的復(fù)用能力。因?yàn)榭梢灾С肿钭笄熬Y,所以當(dāng)已經(jīng)有了 (a,b) 這個(gè)
聯(lián)合索引后,一般就不需要單獨(dú)在 a 上建立索引了。因此,第一原則是,如果通過調(diào)整順序,可
以少維護(hù)一個(gè)索引,那么這個(gè)順序往往就是需要優(yōu)先考慮采用的。
所以現(xiàn)在你知道了,這段開頭的問題里,我們要為高頻請(qǐng)求創(chuàng)建 (身份證號(hào),姓名)這個(gè)聯(lián)合索
引,并用這個(gè)索引支持“根據(jù)身份證號(hào)查詢地址”的需求。
那么,如果既有聯(lián)合查詢,又有基于 a、b 各自的查詢呢?查詢條件里面只有 b 的語句,是無法
使用 (a,b) 這個(gè)聯(lián)合索引的,這時(shí)候你不得不維護(hù)另外一個(gè)索引,也就是說你需要同時(shí)維護(hù)
(a,b)、(b) 這兩個(gè)索引。
這時(shí)候,我們要考慮的原則就是空間了。比如上面這個(gè)市民表的情況,name 字段是比 age 字段
大的 ,那我就建議你創(chuàng)建一個(gè)(name,age) 的聯(lián)合索引和一個(gè) (age) 的單字段索引。
1.UNIQUE 關(guān)鍵字建唯一索引\x0d\x0amysql CREATE TABLE `wb_blog` ( \x0d\x0a - `id` smallint(8) unsigned NOT NULL, \x0d\x0a - `catid` smallint(5) unsigned NOT NULL DEFAULT '0', \x0d\x0a - `title` varchar(80) NOT NULL DEFAULT '', \x0d\x0a - `content` text NOT NULL, \x0d\x0a - PRIMARY KEY (`id`), \x0d\x0a - UNIQUE KEY `catename` (`catid`) \x0d\x0a - ) ; \x0d\x0a如果建好表了,可以用以下語句建\x0d\x0a mysql CREATE UNIQUE INDEX catename ON wb_blog(catid); \x0d\x0a\x0d\x0a2.聯(lián)合索引\x0d\x0aALTER TABLE `tasks`\x0d\x0aADD INDEX `testabc` (`title`, `created`) ;\x0d\x0a\x0d\x0a3聯(lián)合唯一索引(假設(shè)有這個(gè)需求,在同一天內(nèi)不能建兩個(gè)tiltle一樣的任務(wù))\x0d\x0aALTER TABLE `tasks`\x0d\x0aADD UNIQUE INDEX `testabc` (`title`, `created`) ;\x0d\x0a\x0d\x0a數(shù)據(jù)庫建索引的科學(xué)性事關(guān)數(shù)據(jù)庫性能,索引也不是越多越好。