mysql 联合索引 性能_mysql:联合索引及优化
命名規(guī)則:表名_字段名
1、需要加索引的字段,要在where條件中
2、數(shù)據(jù)量少的字段不需要加索引
3、如果where條件中是OR關(guān)系,加索引不起作用
4、符合最左原則
盡量不要用or,如果可以用union代替,則一定要代替
https://segmentfault.com/q/1010000003984016/a-1020000003984281
聯(lián)合索引又叫復(fù)合索引。對(duì)于復(fù)合索引:Mysql從左到右的使用索引中的字段,一個(gè)查詢(xún)可以只使用索引中的一部份,但只能是最左側(cè)部分。例如索引是key index (a,b,c). 可以支持a?|a,b|?a,b,c?3種組合進(jìn)行查找,但不支持 b,c進(jìn)行查找 .當(dāng)最左側(cè)字段是常量引用時(shí),索引就十分有效。
兩個(gè)或更多個(gè)列上的索引被稱(chēng)作復(fù)合索引。
利用索引中的附加列,您可以縮小搜索的范圍,但使用一個(gè)具有兩列的索引 不同于使用兩個(gè)單獨(dú)的索引。復(fù)合索引的結(jié)構(gòu)與電話簿類(lèi)似,人名由姓和名構(gòu)成,電話簿首先按姓氏對(duì)進(jìn)行排序,然后按名字對(duì)有相同姓氏的人進(jìn)行排序。如果您知 道姓,電話簿將非常有用;如果您知道姓和名,電話簿則更為有用,但如果您只知道名不姓,電話簿將沒(méi)有用處。
所以說(shuō)創(chuàng)建復(fù)合索引時(shí),應(yīng)該仔細(xì)考慮列的順序。對(duì)索引中的所有列執(zhí)行搜索或僅對(duì)前幾列執(zhí)行搜索時(shí),復(fù)合索引非常有用;僅對(duì)后面的任意列執(zhí)行搜索時(shí),復(fù)合索引則沒(méi)有用處。
http://blog.csdn.net/lmh12506/article/details/8879916
當(dāng)一個(gè)表有多條索引可走時(shí),? Mysql? 根據(jù)查詢(xún)語(yǔ)句的成本來(lái)選擇走哪條索引, 聯(lián)合索引的話, 它往往計(jì)算的是第一個(gè)字段(最左邊那個(gè)), 這樣往往會(huì)走錯(cuò)索引. 如:
索引Index_1(Create_Time, Category_ID), Index_2(Category_ID)
如果每天的數(shù)據(jù)都特別多, 而且有很多category, 但具體每個(gè)category的記錄不會(huì)很多.
當(dāng)查詢(xún)SQL條件為select …where create_time ….and category_id=..時(shí), 很可能不走索引Index_1, 而走索引Index_2, 導(dǎo)致查詢(xún)比較慢.
解決辦法是將索引字段的順序調(diào)換一下.
http://www.cnblogs.com/krisy/archive/2013/07/12/3186258.html
創(chuàng)建索引
在執(zhí)行CREATE TABLE語(yǔ)句時(shí)可以創(chuàng)建索引,也可以單獨(dú)用CREATE INDEX或ALTER TABLE來(lái)為表增加索引。
1.ALTER TABLE
ALTER TABLE用來(lái)創(chuàng)建普通索引、UNIQUE索引或PRIMARY KEY索引。
ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE (column_list)
ALTER TABLE table_name ADD PRIMARY KEY (column_list)
其中table_name是要增加索引的表名,column_list指出對(duì)哪些列進(jìn)行索引,多列時(shí)各列之間用逗號(hào)分隔。索引名index_name可選,缺省時(shí),MySQL將根據(jù)第一個(gè)索引列賦一個(gè)名稱(chēng)。另外,ALTER TABLE允許在單個(gè)語(yǔ)句中更改多個(gè)表,因此可以在同時(shí)創(chuàng)建多個(gè)索引。
2.CREATE INDEX
CREATE INDEX可對(duì)表增加普通索引或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語(yǔ)句中相同的含義,索引名不可選。另外,不能用CREATE INDEX語(yǔ)句創(chuàng)建PRIMARY KEY索引。
3.索引類(lèi)型
在創(chuàng)建索引時(shí),可以規(guī)定索引能否包含重復(fù)值。如果不包含,則索引應(yīng)該創(chuàng)建為PRIMARY KEY或UNIQUE索引。對(duì)于單列惟一性索引,這保證單列不包含重復(fù)的值。對(duì)于多列惟一性索引,保證多個(gè)值的組合不重復(fù)。
PRIMARY KEY索引和UNIQUE索引非常類(lèi)似。
事實(shí)上,PRIMARY KEY索引僅是一個(gè)具有名稱(chēng)PRIMARY的UNIQUE索引。這表示一個(gè)表只能包含一個(gè)PRIMARY KEY,因?yàn)橐粋€(gè)表中不可能具有兩個(gè)同名的索引。
下面的SQL語(yǔ)句對(duì)students表在sid上添加PRIMARY KEY索引。
ALTER TABLE students ADD PRIMARY KEY (sid)
4.??刪除索引
可利用ALTER TABLE或DROP INDEX語(yǔ)句來(lái)刪除索引。類(lèi)似于CREATE INDEX語(yǔ)句,DROP INDEX可以在ALTER TABLE內(nèi)部作為一條語(yǔ)句處理,語(yǔ)法如下。
DROP INDEX index_name ON talbe_name
ALTER TABLE table_name DROP INDEX index_name
ALTER TABLE table_name DROP PRIMARY KEY
其中,前兩條語(yǔ)句是等價(jià)的,刪除掉table_name中的索引index_name。
第3條語(yǔ)句只在刪除PRIMARY KEY索引時(shí)使用,因?yàn)橐粋€(gè)表只可能有一個(gè)PRIMARY KEY索引,因此不需要指定索引名。如果沒(méi)有創(chuàng)建PRIMARY KEY索引,但表具有一個(gè)或多個(gè)UNIQUE索引,則MySQL將刪除第一個(gè)UNIQUE索引。
如果從表中刪除了某列,則索引會(huì)受到影響。對(duì)于多列組合的索引,如果刪除其中的某列,則該列也會(huì)從索引中刪除。如果刪除組成索引的所有列,則整個(gè)索引將被刪除。
5.查看索引
mysql> show?index from tblname;
mysql> show keys from tblname;
· Table
表的名稱(chēng)。
· Non_unique
如果索引不能包括重復(fù)詞,則為0。如果可以,則為1。
· Key_name
索引的名稱(chēng)。
· Seq_in_index
索引中的列序列號(hào),從1開(kāi)始。
· Column_name
列名稱(chēng)。
· Collation
列以什么方式存儲(chǔ)在索引中。在MySQL中,有值‘A’(升序)或NULL(無(wú)分類(lèi))。
· Cardinality
索引中唯一值的數(shù)目的估計(jì)值。通過(guò)運(yùn)行ANALYZE TABLE或myisamchk -a可以更新。基數(shù)根據(jù)被存儲(chǔ)為整數(shù)的統(tǒng)計(jì)數(shù)據(jù)來(lái)計(jì)數(shù),所以即使對(duì)于小型表,該值也沒(méi)有必要是精確的。基數(shù)越大,當(dāng)進(jìn)行聯(lián)合時(shí),MySQL使用該索引的機(jī)會(huì)就越大。
· Sub_part
如果列只是被部分地編入索引,則為被編入索引的字符的數(shù)目。如果整列被編入索引,則為NULL。
· Packed
指示關(guān)鍵字如何被壓縮。如果沒(méi)有被壓縮,則為NULL。
· Null
如果列含有NULL,則含有YES。如果沒(méi)有,則該列含有NO。
· Index_type
用過(guò)的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
· Comment
6.什么情況下使用索引表的主關(guān)鍵字
自動(dòng)建立唯一索引
如zl_yhjbqk(用戶(hù)基本情況)中的hbs_bh(戶(hù)標(biāo)識(shí)編號(hào))
表的字段唯一約束
ORACLE利用索引來(lái)保證數(shù)據(jù)的完整性
如lc_hj(流程環(huán)節(jié))中的lc_bh+hj_sx(流程編號(hào)+環(huán)節(jié)順序)
直接條件查詢(xún)的字段
在SQL中用于條件約束的字段
如zl_yhjbqk(用戶(hù)基本情況)中的qc_bh(區(qū)冊(cè)編號(hào))
select * from zl_yhjbqk where qc_bh=’???甼曀???>7001’
查詢(xún)中與其它表關(guān)聯(lián)的字段
字段常常建立了外鍵關(guān)系
如zl_ydcf(用電成份)中的jldb_bh(計(jì)量點(diǎn)表編號(hào))
select * from zl_ydcf a,zl_yhdb b where a.jldb_bh=b.jldb_bh and b.jldb_bh=’540100214511’
查詢(xún)中排序的字段
排序的字段如果通過(guò)索引去訪問(wèn)那將大大提高排序速度
select * from zl_yhjbqk order by qc_bh(建立qc_bh索引)
select * from zl_yhjbqk where qc_bh=’7001’ order by cb_sx(建立qc_bh+cb_sx索引,注:只是一個(gè)索引,其中包括qc_bh和cb_sx字段)
查詢(xún)中統(tǒng)計(jì)或分組統(tǒng)計(jì)的字段
select max(hbs_bh) from zl_yhjbqk
select qc_bh,count(*) from zl_yhjbqk group by qc_bh
什么情況下應(yīng)不建或少建索引
表記錄太少
如果一個(gè)表只有5條記錄,采用索引去訪問(wèn)記錄的話,那首先需訪問(wèn)索引表,再通過(guò)索引表訪問(wèn)數(shù)據(jù)表,一般索引表與數(shù)據(jù)表不在同一個(gè)數(shù)據(jù)塊,這種情況下ORACLE至少要往返讀取數(shù)據(jù)塊兩次。而不用索引的情況下ORACLE會(huì)將所有的數(shù)據(jù)一次讀出,處理速度顯然會(huì)比用索引快。
如表zl_sybm(使用部門(mén))一般只有幾條記錄,除了主關(guān)鍵字外對(duì)任何一個(gè)字段建索引都不會(huì)產(chǎn)生性能優(yōu)化,實(shí)際上如果對(duì)這個(gè)表進(jìn)行了統(tǒng)計(jì)分析后ORACLE也不會(huì)用你建的索引,而是自動(dòng)執(zhí)行全表訪問(wèn)。如:
select * from zl_sybm where sydw_bh=’5401’(對(duì)sydw_bh建立索引不會(huì)產(chǎn)生性能優(yōu)化)
經(jīng)常插入、刪除、修改的表
對(duì)一些經(jīng)常處理的業(yè)務(wù)表應(yīng)在查詢(xún)?cè)试S的情況下盡量減少索引,如zl_yhbm,gc_dfss,gc_dfys,gc_fpdy等業(yè)務(wù)表。
數(shù)據(jù)重復(fù)且分布平均的表字段
假如一個(gè)表有10萬(wàn)行記錄,有一個(gè)字段A只有T和F兩種值,且每個(gè)值的分布概率大約為50%,那么對(duì)這種表A字段建索引一般不會(huì)提高數(shù)據(jù)庫(kù)的查詢(xún)速度。
經(jīng)常和主字段一塊查詢(xún)但主字段索引值比較多的表字段
如gc_dfss(電費(fèi)實(shí)收)表經(jīng)常按收費(fèi)序號(hào)、戶(hù)標(biāo)識(shí)編號(hào)、抄表日期、電費(fèi)發(fā)生年月、操作 標(biāo)志來(lái)具體查詢(xún)某一筆收款的情況,如果將所有的字段都建在一個(gè)索引里那將會(huì)增加數(shù)據(jù)的修改、插入、刪除時(shí)間,從實(shí)際上分析一筆收款如果按收費(fèi)序號(hào)索引就已 經(jīng)將記錄減少到只有幾條,如果再按后面的幾個(gè)字段索引查詢(xún)將對(duì)性能不產(chǎn)生太大的影響。
對(duì)千萬(wàn)級(jí)MySQL數(shù)據(jù)庫(kù)建立索引的事項(xiàng)及提高性能的手段
一、注意事項(xiàng):
首先,應(yīng)當(dāng)考慮表空間和磁盤(pán)空間是否足夠。我們知道索引也是一種數(shù)據(jù),在建立索引的時(shí)候勢(shì)必也會(huì)占用大量表空間。因此在對(duì)一大表建立索引的時(shí)候首先應(yīng)當(dāng)考慮的是空間容量問(wèn)題。
其次,在對(duì)建立索引的時(shí)候要對(duì)表進(jìn)行加鎖,因此應(yīng)當(dāng)注意操作在業(yè)務(wù)空閑的時(shí)候進(jìn)行。
二、性能調(diào)整方面:
首當(dāng)其沖的考慮因素便是磁盤(pán)I/O。物理上,應(yīng)當(dāng)盡量把索引與數(shù)據(jù)分散到不同的磁盤(pán)上(不考慮陣列的情況)。邏輯上,數(shù)據(jù)表空間與索引表空間分開(kāi)。這是在建索引時(shí)應(yīng)當(dāng)遵守的基本準(zhǔn)則。
其次,我們知道,在建立索引的時(shí)候要對(duì)表進(jìn)行全表的掃描工作,因此,應(yīng)當(dāng)考慮調(diào)大初始化參數(shù)db_file_multiblock_read_count的值。一般設(shè)置為32或更大。
再次,建立索引除了要進(jìn)行全表掃描外同時(shí)還要對(duì)數(shù)據(jù)進(jìn)行大量的排序操作,因此,應(yīng)當(dāng)調(diào)整排序區(qū)的大小。
9i之前,可以在session級(jí)別上加大sort_area_size的大小,比如設(shè)置為100m或者更大。
9i以后,如果初始化參數(shù)workarea_size_policy的值為T(mén)RUE,則排序區(qū)從pga_aggregate_target里自動(dòng)分配獲得。
最后,建立索引的時(shí)候,可以加上nologging選項(xiàng)。以減少在建立索引過(guò)程中產(chǎn)生的大量redo,從而提高執(zhí)行的速度。
MySql在建立索引優(yōu)化時(shí)需要注意的問(wèn)題
設(shè)計(jì)好MySql的索引可以讓你的數(shù)據(jù)庫(kù)飛起來(lái),大大的提高數(shù)據(jù)庫(kù)效率。設(shè)計(jì)MySql索引的時(shí)候有一下幾點(diǎn)注意:
1,創(chuàng)建索引
對(duì)于查詢(xún)占主要的應(yīng)用來(lái)說(shuō),索引顯得尤為重要。很多時(shí)候性能問(wèn)題很簡(jiǎn)單的就是因?yàn)槲覀兺颂砑铀饕斐傻?#xff0c;或者說(shuō)沒(méi)有添加更為有效的索引導(dǎo)致。如果不加
索引的話,那么查找任何哪怕只是一條特定的數(shù)據(jù)都會(huì)進(jìn)行一次全表掃描,如果一張表的數(shù)據(jù)量很大而符合條件的結(jié)果又很少,那么不加索引會(huì)引起致命的性能下降。
但是也不是什么情況都非得建索引不可,比如性別可能就只有兩個(gè)值,建索引不僅沒(méi)什么優(yōu)勢(shì),還會(huì)影響到更新速度,這被稱(chēng)為過(guò)度索引。
2,復(fù)合索引
比如有一條語(yǔ)句是這樣的:select * from users where area=’beijing’ and age=22;
如果我們是在area和age上分別創(chuàng)建單個(gè)索引的話,由于mysql查詢(xún)每次只能使用一個(gè)索引,所以雖然這樣已經(jīng)相對(duì)不做索引時(shí)全表掃描提高了很多效
率,但是如果在area、age兩列上創(chuàng)建復(fù)合索引的話將帶來(lái)更高的效率。如果我們創(chuàng)建了(area, age,salary)的復(fù)合索引,那么其實(shí)相當(dāng)于創(chuàng)建了(area,age,salary)、(area,age)、(area)三個(gè)索引,這被稱(chēng)為最佳左前綴特性。
因此我們?cè)趧?chuàng)建復(fù)合索引時(shí)應(yīng)該將最常用作限制條件的列放在最左邊,依次遞減。
3,索引不會(huì)包含有NULL值的列
只要列中包含有NULL值都將不會(huì)被包含在索引中,復(fù)合索引中只要有一列含有NULL值,那么這一列對(duì)于此復(fù)合索引就是無(wú)效的。所以我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)時(shí)不要讓字段的默認(rèn)值為NULL。
4,使用短索引
對(duì)串列進(jìn)行索引,如果可能應(yīng)該指定一個(gè)前綴長(zhǎng)度。例如,如果有一個(gè)CHAR(255)的 列,如果在前10 個(gè)或20 個(gè)字符內(nèi),多數(shù)值是惟一的,那么就不要對(duì)整個(gè)列進(jìn)行索引。短索引不僅可以提高查詢(xún)速度而且可以節(jié)省磁盤(pán)空間和I/O操作。
5,排序的索引問(wèn)題
mysql查詢(xún)只使用一個(gè)索引,因此如果where子句中已經(jīng)使用了索引的話,那么order by中的列是不會(huì)使用索引的。因此數(shù)據(jù)庫(kù)默認(rèn)排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個(gè)列的排序,如果需要最好給這些列創(chuàng)建復(fù)合索引。
6,like語(yǔ)句操作
一般情況下不鼓勵(lì)使用like操作,如果非使用不可,如何使用也是一個(gè)問(wèn)題。like “%aaa%” 不會(huì)使用索引而like “aaa%”可以使用索引。
7,不要在列上進(jìn)行運(yùn)算
select * from users where
YEAR(adddate)
8,不使用NOT IN和 <> 和 != 操作
NOT IN和操作都不會(huì)使用索引將進(jìn)行全表掃描。NOT IN可以NOT EXISTS(>, =, <=)代替,id3則可使用id>3 or id
總結(jié)
以上是生活随笔為你收集整理的mysql 联合索引 性能_mysql:联合索引及优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux下查看进程的线程数,linux
- 下一篇: mysql 分析服务_MySQL分析服务