提供了相似於書中目錄的做用,目的是爲了優化查詢html
大的分類:mysql
B樹索引 Hash索引 R樹 Full text GIS #地圖類索引 ------------------------------- #B樹基於不一樣的查找算法分類: B-tree 如下兩種類型在範圍查詢方面提供了更好的性能(> < >= <=) B+Tree B*Tree
1)輔助索引(S)怎麼構建B樹結構的?linux
2)輔助索引細分面試
1)前提redis
2)彙集索引(C)怎麼構建B樹結構的?算法
1)數據量級, 解決方法:分表,分庫,分佈式sql
2)索引列值過長 , 解決方法:前綴索引mongodb
3)數據類型: 數據庫
變長長度字符串,使用了char,解決方案:變長字符串使用varcharvim
enum類型的使用enum ('山東','河北','黑龍江','吉林','遼寧','陝西'......)
mysql> desc city; +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | CountryCode | char(3) | NO | MUL | | | | District | char(20) | NO | | | | | Population | int(11) | NO | | 0 | | +-------------+----------+------+-----+---------+----------------+ Field :列名字 key :有沒有索引,索引類型 PRI: 主鍵索引 UNI: 惟一索引 MUL: 輔助索引(單列,聯和,前綴) mysql> show index from city; +-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | city | 0 | PRIMARY | 1 | ID | A | 4188 | NULL | NULL | | BTREE | | | | city | 1 | CountryCode | 1 | CountryCode | A | 4188 | NULL | NULL | | BTREE | | | +-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1)建立索引
alter table city add index idx_name(name); #方法一 create index idx_name1 on city(name); #方法二 show index from city;
2)刪除索引
alter table city drop index idx_name1; #直接刪除索引名稱便可
3)覆蓋索引(聯合索引)
alter table city add key idx_co_po(countrycode,population); #多個字段上創建索引 alter table city add index idx_co_po(countrycode,population); #多個字段上創建索引
4)前綴索引
alter table city add index idx_di(district(5)); #在前5個字符上創建索引
5)惟一索引
alter table city add unique index idx_uni1(name); ERROR 1062 (23000): Duplicate entry 'San Jose' for key 'idx_uni1' #惟一鍵衝突
獲取到的是優化器選擇完成的,他認爲代價最小的執行計劃.
做用: 語句執行前,先看執行計劃信息,能夠有效的防止性能較差的語句帶來的性能問題.
1. 全表掃描(應當儘可能避免,由於性能低)
2. 索引掃描
3. 獲取不到數據
獲取優化器選擇後的執行計劃:explain或者desc
explain select SQL_NO_CACHE * from test where name='AAA'\G #SQL_NO_CACHE的做用是禁止緩存查詢結果。
mysql> desc select * from city where countrycode='CHN'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: city partitions: NULL type: ref possible_keys: CountryCode key: CountryCode key_len: 3 ref: const rows: 363 filtered: 100.00 Extra: NULL --------------------------------------------------------------- #執行計劃相關信息分析: table: city #查詢操做的表 possible_keys: CountryCode,idx_co_po #可能會走的索引 key: CountryCode #真正走的索引 type: ref #索引類型 Extra: Using index condition #額外信息
以下爲索引類型,從左到右性能依次變好.
ALL #全表掃描 index #全索引掃描 range #索引範圍查詢 ref #輔助索引的等值查詢 eq_ref #多表鏈接的表,On的條件是主鍵或惟一鍵 system(const) #主鍵或惟一鍵的等值查詢 NULL #索引中掃描不到這個數據
在索引掃描類型方面,至少保證在range以上級別。
desc select * from city; desc select * from city where name like '%C%'; desc select * from city where name != 'CHN'; #或者<> desc select * from city where countrycode not in ('CHN','USA'); #注意:生產中幾乎是沒有這種需求的。儘可能避免
須要掃描整個索引樹,獲取到想要數據,比ALL性能好,順序IO,能夠減小回表查詢
mysql> desc city; +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | CountryCode | char(3) | NO | MUL | | | | District | char(20) | NO | | | | | Population | int(11) | NO | | 0 | | +-------------+----------+------+-----+---------+----------------+ mysql> desc select CountryCode from city; +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+ | 1 | SIMPLE | city | NULL | index | NULL | CountryCode | 3 | NULL | 4188 | 100.00 | Using index | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
> < >= <= in or like 'CH%' between and --------------------------------------------------- 注意: B+樹額外優化了 > < >= <= between and like 'CH%' in or沒法享受B+樹的額外優化,能夠用union all來替代
mysql> desc select * from city where id<10; +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | 1 | SIMPLE | city | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 9 | 100.00 | Using where | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ mysql> desc select * from city where countrycode in ('CHN','USA'); +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | city | NULL | range | CountryCode | CountryCode | 3 | NULL | 637 | 100.00 | Using index condition | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ mysql> desc select * from city where countrycode like 'CH%'; +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | city | NULL | range | CountryCode | CountryCode | 3 | NULL | 397 | 100.00 | Using index condition | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
mysql> desc select * from city where countrycode in ('CHN','USA'); +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | city | NULL | range | CountryCode | CountryCode | 3 | NULL | 637 | 100.00 | Using index condition | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ mysql> desc select * from city where countrycode='CHN' union all select * from city where countrycode='USA'; +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+ | 1 | PRIMARY | city | NULL | ref | CountryCode | CountryCode | 3 | const | 363 | 100.00 | NULL | | 2 | UNION | city | NULL | ref | CountryCode | CountryCode | 3 | const | 274 | 100.00 | NULL | +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
mysql> desc select * from city where countrycode = 'CHN'; +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+ | 1 | SIMPLE | city | NULL | ref | CountryCode | CountryCode | 3 | const | 363 | 100.00 | NULL | +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
多表鏈接的表,On的條件是主鍵或惟一鍵
主鍵或惟一鍵的等值查詢
mysql> desc select * from city where id=10; +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | city | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
索引中掃描不到這個數據
mysql> desc select * from city where id=5000; #id=5000不存在 +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | no matching row in const table | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
Extra字段:Using filesort #出現說明有問題,要優化 desc select * from city where countrycode='CHN' order by population desc limit 10; #contrycode上有索引,但population上是沒有索引的 mysql> desc select * from city where countrycode='CHN' order by population desc limit 10; +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+---------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+---------------------------------------+ | 1 | SIMPLE | city | NULL | ref | CountryCode | CountryCode | 3 | const | 363 | 100.00 | Using index condition; Using filesort | +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+---------------------------------------+ #解決思路: 索引能夠減小排序,能夠很大程度減小CPU時間 輔助索引 應用順序(優化器選擇的) 若是查詢條件:符合覆蓋索引的順序時,優先選擇覆蓋索引 不符合順序,優先會走where條件的索引 #解決方法:能夠在countrycode和population上創建聯合索引 mysql> alter table city add index idx_po(countrycode,population); mysql> desc select * from city where countrycode='CHN' order by population limit 10; +----+-------------+-------+------------+------+--------------------+--------+---------+-------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+--------------------+--------+---------+-------+------+----------+-----------------------+ | 1 | SIMPLE | city | NULL | ref | CountryCode,idx_po | idx_po | 3 | const | 363 | 100.00 | Using index condition | +----+-------------+-------+------------+------+--------------------+--------+---------+-------+------+----------+-----------------------+
面試:咱們公司業務慢,請你從數據庫的角度分析緣由? mysql出現性能問題,總結有兩種狀況: (1)應急性的慢:忽然夯住 應急狀況:數據庫hang(卡了,資源耗盡) 處理過程: (1)show processlist; #獲取到致使數據庫hang住的語句 (2)explain #分析SQL的執行計劃,有沒有走索引,索引的類型狀況 (3)建索引,改語句 (2)一段時間慢(持續性的): (1)記錄慢日誌slowlog,分析slowlog (2)explain 分析SQL的執行計劃,有沒有走索引,索引的類型狀況 (3)建索引,改語句
mysqlslap工具介紹 mysqlslap來自於mariadb包,測試的過程默認生成一個mysqlslap的schema,生成測試表t1,查詢和插入測試數據,mysqlslap庫自動生成,若是已經存在則先刪除。用--only-print來打印實際的測試過程,整個測試完成後不會在數據庫中留下痕跡。 經常使用選項: --auto-generate-sql, -a 自動生成測試表和數據,表示用mysqlslap工具本身生成的SQL腳原本測試併發壓力 --auto-generate-sql-load-type=type 測試語句的類型。表明要測試的環境是讀操做仍是寫操做仍是二者混合的。取值包括:read,key,write,update和mixed(默認) --auto-generate-sql-add-auto-increment 表明對生成的表自動添加auto_increment列,從5.1.18版本開始支持 --number-char-cols=N, -x N 自動生成的測試表中包含多少個字符類型的列,默認1 --number-int-cols=N, -y N 自動生成的測試表中包含多少個數字類型的列,默認1 --number-of-queries=N 總的測試查詢次數(併發客戶數×每客戶查詢次數) --query=name,-q 使用自定義腳本執行測試,例如能夠調用自定義的存儲過程或者sql語句來執行測試 --create-schema 表明自定義的測試庫名稱,測試的schema,MySQL中schema也就是database --commint=N 多少條DML後提交一次 --compress, -C 如服務器和客戶端都支持壓縮,則壓縮信息 --concurrency=N, -c N 表示併發量,即模擬多少個客戶端同時執行select;可指定多個值,以逗號或者--delimiter參數指定值作爲分隔符 --engine=engine_name, -e engine_name 表明要測試的引擎,能夠有多個,用分隔符隔開 --iterations=N, -i N 測試執行的迭代次數,表明要在不一樣併發環境下,各自運行測試多少次 --only-print 只打印測試語句而不實際執行 --detach=N 執行N條語句後斷開重連 --debug-info, -T 打印內存和CPU的相關信息 測試示例: 1)單線程測試 [root@centos7 ~]# mysqlslap -a -uroot -p Enter password: Benchmark Average number of seconds to run all queries: 0.004 seconds Minimum number of seconds to run all queries: 0.004 seconds Maximum number of seconds to run all queries: 0.004 seconds Number of clients running queries: 1 Average number of queries per client: 0 2)多線程測試,使用--concurrency來模擬併發鏈接 [root@centos7 ~]# mysqlslap -uroot -p -a -c 500 Enter password: Benchmark Average number of seconds to run all queries: 3.384 seconds Minimum number of seconds to run all queries: 3.384 seconds Maximum number of seconds to run all queries: 3.384 seconds Number of clients running queries: 500 Average number of queries per client: 0 3)同時測試不一樣的存儲引擎的性能進行對比 [root@centos7 ~]# mysqlslap -uroot -p -a --concurrency=500 --number-of-queries 1000 --iterations=5 --engine=myisam,innodb --debug-info Enter password: Benchmark Running for engine myisam Average number of seconds to run all queries: 0.192 seconds Minimum number of seconds to run all queries: 0.187 seconds Maximum number of seconds to run all queries: 0.202 seconds Number of clients running queries: 500 Average number of queries per client: 2 Benchmark Running for engine innodb Average number of seconds to run all queries: 0.355 seconds Minimum number of seconds to run all queries: 0.350 seconds Maximum number of seconds to run all queries: 0.364 seconds Number of clients running queries: 500 Average number of queries per client: 2 User time 0.33, System time 0.58 Maximum resident set size 22892, Integral resident set size 0 Non-physical pagefaults 46012, Physical pagefaults 0, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 31896, Involuntary context switches 0 4)執行一次測試,分別500和1000個併發,執行5000次總查詢 [root@centos7 ~]# mysqlslap -uroot -p -a --concurrency=500,1000 --number-of-queries 5000 --debug-info Enter password: Benchmark Average number of seconds to run all queries: 3.378 seconds Minimum number of seconds to run all queries: 3.378 seconds Maximum number of seconds to run all queries: 3.378 seconds Number of clients running queries: 500 Average number of queries per client: 10 Benchmark Average number of seconds to run all queries: 3.101 seconds Minimum number of seconds to run all queries: 3.101 seconds Maximum number of seconds to run all queries: 3.101 seconds Number of clients running queries: 1000 Average number of queries per client: 5 User time 0.84, System time 0.64 Maximum resident set size 83068, Integral resident set size 0 Non-physical pagefaults 139977, Physical pagefaults 0, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 31524, Involuntary context switches 3 5)迭代測試 [root@centos7 ~]# mysqlslap -uroot -p -a --concurrency=500 --number-of-queries 5000 --iterations=5 --debug-info Enter password: Benchmark Average number of seconds to run all queries: 3.307 seconds Minimum number of seconds to run all queries: 3.184 seconds Maximum number of seconds to run all queries: 3.421 seconds Number of clients running queries: 500 Average number of queries per client: 10 User time 2.18, System time 1.58 Maximum resident set size 74872, Integral resident set size 0 Non-physical pagefaults 327732, Physical pagefaults 0, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 73904, Involuntary context switches 3
1)模擬數據庫數據
drop database oldboy; create database oldboy charset utf8;
2)建立一個t1的表,而後導入50萬行數據
[root@db01 ~]# vim slap.sh #!/bin/bash HOSTNAME="localhost" PORT="3306" USERNAME="root" PASSWORD="1" DBNAME="oldboy" TABLENAME="t1" #create database mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} -e "drop database if exists ${DBNAME}" create_db_sql="create database if not exists ${DBNAME}" mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} -e "${create_db_sql}" #create table create_table_sql="create table if not exists ${TABLENAME}(stuid int not null primary key,stuname varchar(20) not null,stusex char(1) not null,cardid varchar(20) not null,birthday datetime,entertime datetime,address varchar(100)default null)" mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e "${create_table_sql}" #insert data to table i="1" while [ $i -le 500000 ] do insert_sql="insert into ${TABLENAME} values($i,'alexsb_$i','1','110011198809163418','1990-05-16','2017-09-13','oldboyedu')" mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e "${insert_sql}" let i++ done #select data select_sql="select count(*) from ${TABLENAME}" mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e "${select_sql}" 執行腳本: sh slap.sh 或者直接source drop database oldboy; source /root/oldboy.sql
3)檢查數據可用性
mysql -uroot -p select count(*) from oldboy.t1;
4)使用mysqlslap來進行壓力測試
mysqlslap --defaults-file=/etc/my.cnf \ --concurrency=100 --iterations=1 --create-schema='oldboy' \ --query="select * from oldboy.t1 where stuname='alexsb_100'" engine=innodb \ --number-of-queries=2000 -uroot -pmysql -verbose
沒創建索引以前:
在查詢條件列上創建索引:alter table t1 add index idx_name(stuname);
1)tpcc
2)sysbench
主要根據公司的業務來創建合適的索引
爲了使索引的使用效率更高,在建立索引時,必須考慮在哪些字段上建立索引和建立什麼類型的索引。
1)建表時必定要有主鍵,通常是個無關列(必須)
2)選擇惟一鍵索引
惟一性索引的值是惟一的,能夠更快速的經過該索引來肯定某條記錄。 #優化方案: (1) 若是非得使用重複值較多的列做爲查詢條件(例如:男女),能夠將表邏輯拆分 (2) 能夠將此列和其餘的查詢類,作聯和索引 #如何判斷索引列有多少是惟一值? select count(*) from world.city; select count(distinct countrycode) from world.city; select count(distinct countrycode,population ) from world.city;
3)爲常常須要where 、ORDER BY、GROUP BY,join on等操做的字段創建索引,排序操做會浪費不少時間。注:若是常常做爲條件的列,重複值特別多,能夠創建聯合索引
4)使用前綴索引。若是索引字段的值很長,最好使用值的前綴來索引。
5)限制索引的數目
索引的數目不是越多越好。可能會產生的問題: (1) 每一個索引都須要佔用磁盤空間,索引越多,須要的磁盤空間就越大。 (2) 修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。 (3) 優化器的負擔會很重,有可能會影響到優化器的選擇.
6)刪除再也不使用或者不多使用的索引(使用percona toolkit)
表中的數據被大量更新,或者數據的使用方式被改變後,原有的一些索引可能再也不須要。數據庫管理 員應當按期找出這些索引,將它們刪除,從而減小索引對更新操做的影響。
7)大表加索引,要在業務不繁忙期間操做
8)儘可能少在常常更新值的列上建索引
創建索引原則總結:
(1) 必需要有主鍵,若是沒有能夠作爲主鍵條件的列,建立無關列 (2) 常常作爲where條件列 order by group by join on, distinct 的條件(業務:產品功能+用戶行爲) (3) 最好使用惟一值多的列做爲索引,若是索引列重複值較多,能夠考慮使用聯合索引 (4) 列值長度較長的索引列,咱們建議使用前綴索引. (5) 下降索引條目,一方面不要建立沒用索引,不常使用的索引清理,使用percona toolkit工具 (6) 索引維護要避開業務繁忙期
1)沒有查詢條件,或者查詢條件沒有創建索引
select * from tab; #全表掃描 select * from tab where 1=1;
在業務數據庫中,特別是數據量比較大的表,是沒有全表掃描這種需求。
(1)select * from tab; SQL改寫成如下語句: selec * from tab order by price limit 10 ; #須要在price列上創建索引 (2)select * from tab where name='zhangsan' #name列沒有索引 改爲以下語句: 一、換成有索引的列做爲查詢條件 二、將name列創建索引
2)查詢的結果集,超過了總數行數25%,優化器默認沒有必要走索引
解決方法: 一、若是業務容許,可使用limit控制。 二、儘可能不要在mysql存放這個數據了,能夠放到redis裏面
3)索引自己失效,統計數據不真實
索引有自我維護的能力。對於表內容變化比較頻繁的狀況下,有可能會出現索引失效。通常是刪除重建
4)查詢條件使用函數在索引列上,或者對索引列進行運算,運算包括(+,-,*,/,! 等)
錯誤的例子:select * from test where id-1=9; 正確的例子:select * from test where id=10; 在索引列上使用算術運算,函數運算,子查詢時,可能不會走索引
5)隱式轉換致使索引失效
mysql> alter table tab add index inx_tel(telnum); mysql> desc tab; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(20) | YES | | NULL | | | telnum | varchar(20) | YES | MUL | NULL | | #字段類型是varchar,同時創建了索引 +--------+-------------+------+-----+---------+-------+ mysql> select * from tab where telnum='1333333'; #查詢條件是字符串,走索引 +------+------+---------+ | id | name | telnum | +------+------+---------+ | 1 | a | 1333333 | +------+------+---------+ mysql> select * from tab where telnum=1333333; #查詢條件是數字,隱式轉換爲字符串 +------+------+---------+ | id | name | telnum | +------+------+---------+ | 1 | a | 1333333 | +------+------+---------+ mysql> explain select * from tab where telnum='1333333'; +----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+ | 1 | SIMPLE | tab | ref | inx_tel | inx_tel | 63 | const | 1 | Using index condition | +----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+ mysql> explain select * from tab where telnum=1333333; +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | tab | ALL | inx_tel | NULL | NULL | NULL | 2 | Using where | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
6)<> ,not in 不走索引
EXPLAIN SELECT * FROM teltab WHERE telnum <> '110'; EXPLAIN SELECT * FROM teltab WHERE telnum NOT IN ('110','119'); 注意: 1. 單獨的>,<,in 有可能走,也有可能不走,和結果集有關,儘可能結合業務添加limit 2. or或in 儘可能改爲union EXPLAIN SELECT * FROM teltab WHERE telnum IN ('110','119'); 改寫成: EXPLAIN SELECT * FROM teltab WHERE telnum='110' UNION ALL SELECT * FROM teltab WHERE telnum='119'
7)like "%_" 百分號在最前面不走
EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '31%' #走range索引掃描 EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '%110' #不走索引 %linux%類的搜索需求,可使用elasticsearch+mongodb 專門作搜索服務的數據庫產品
8)單獨引用聯合索引裏非第一位置的索引列.做爲條件查詢時不走索引
idx_a_b_c(a,b,c) #創建的聯合索引 走索引的狀況: where a b c where a b where a ============ 部分走索引 where a c where a c b ============ 不走索引 where c where b where bc where cb where ca where cba