建表語句
create table if not exists `article` (
`id` int(10) unsigned not null primary key auto_increment,
`author_id` int(10) unsigned not null,
`category_id` int(10) unsigned not null,
`views` int(10) unsigned not null,
`comments` int(10) unsigned not null,
`title` varbinary(255) not null,
`content` text not null
insert into `article`(`author_id`, `category_id`, `views`, `comments`, `title`, `content`) values
(1, 1, 1, 1, '1', '1'),
(2, 2, 2, 2, '2', '2'),
(1, 1, 3, 3, '3', '3');
查詢索引
mysql> show index from article;
| table | non_unique | key_name | seq_in_index | column_name | collation | cardinality | sub_part | packed | null | index_type | comment | index_comment |
| article | 0 | primary | 1 | id | a | 3 | null | null | | btree | | |
1 row in set (0.00 sec)
table
non_unique: 非唯一索引(0為唯一索引, 1 為非唯一索引)
key_name: 表示索引的名稱
seq_in_index: 表示該字段在索引中的位置,單列索引改值該值為1,組合索引為每個欄位在索引中定義的順序
column_name: 列名
collation: 字元序的規則
cardinality: 基數
sub_part: 表示索引的長度
packed: 是否建立壓縮的索引(1, 0 與 default)
null: 表示該欄位是否能為空值
index_type: 表示索引型別
comment: 注釋
index_comment: 索引注釋
用explain查詢sql
mysql> explain select id, author_id from article where category_id = 1 and comments > 1 order by views desc limit 1;
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |
| 1 | ****** | article | null | all | null | null | null | null | 3 | 33.33 | using where; using filesort |
1 row in set, 1 warning (0.00 sec)
可以看到type為all(全表查詢), extra中有using filesort(使用了外部索引排序, 而不是按照表內索引順序進行讀取)。
需要進行優化, 不然資料量大後就比較危險。
建立復合索引
mysql> create index idx_article_ccv on article(category_id,comments,views);
query ok, 0 rows affected (0.01 sec)
records: 0 duplicates: 0 warnings: 0
展示該錶的索引
mysql> show index from article;
| table | non_unique | key_name | seq_in_index | column_name | collation | cardinality | sub_part | packed | null | index_type | comment | index_comment |
| article | 0 | primary | 1 | id | a | 3 | null | null | | btree | | |
| article | 1 | idx_article_ccv | 1 | category_id | a | 2 | null | null | | btree | | |
| article | 1 | idx_article_ccv | 2 | comments | a | 3 | null | null | | btree | | |
| article | 1 | idx_article_ccv | 3 | views | a | 3 | null | null | | btree | | |
4 rows in set (0.00 sec)
再次使用explain查詢sql
mysql> explain select id, author_id from article where category_id = 1 and comments > 1 order by views desc limit 1;
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |
| 1 | ****** | article | null | range | idx_article_ccv | idx_article_ccv | 8 | null | 1 | 100.00 | using index condition; using filesort |
1 row in set, 1 warning (0.00 sec)
可以看到type從all變成了range, 但是依舊走的外部索引排序, 而不是按照表內索引順序進行讀取。
索引失效的原理:
使用的是b+樹
先排序 category_id
如果遇到相同的 category_id 則再排序 comments, 如果遇到相同的 comments 則再排序 views。
當 comments 欄位在聯合索引裡處於中間位置時, 因comments > 1 條件是乙個範圍值(所謂range)
mysql 無法利用索引再對後面的 views 部分進行檢索, 即range 型別查詢字段後面的索引無效。
刪除原先索引, 構建新索引
刪除索引
drop index idx_article_ccv on article;
建立新索引(避開了有範圍條件的comments, 從而不會造成索引失效)
create index idx_article_cv on article(category_id, views);
再次檢視索引
mysql> show index from article;
| table | non_unique | key_name | seq_in_index | column_name | collation | cardinality | sub_part | packed | null | index_type | comment | index_comment |
| article | 0 | primary | 1 | id | a | 3 | null | null | | btree | | |
| article | 1 | idx_article_cv | 1 | category_id | a | 2 | null | null | | btree | | |
| article | 1 | idx_article_cv | 2 | views | a | 3 | null | null | | btree | | |
3 rows in set (0.00 sec)
再次使用explain檢視sql語句
explain select id, author_id from article where category_id = 1 and comments > 1 order by views desc limit 1;
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |
| 1 | ****** | article | null | ref | idx_article_cv | idx_article_cv | 4 | const | 2 | 33.33 | using where |
1 row in set, 1 warning (0.00 sec)
可以看到type變為了ref, extra中的file sorting消失了。
mysql 索引 單錶優化
索引分析 type 為 all using filesort 自己進行了排序沒有用到索引 檢視 article 表有什麼索引 show index from article 只有乙個主鍵 建立索引 where 後面的字段需要建索引,但不一定必須建。嘗試著去建 alter table 表名 add i...
MySQL索引優化(索引單錶優化案例)
1 單錶查詢優化 建表sql 案例 查詢 category id 為1 且 comments 大於 1 的情況下,views 最多的 article id。執行sql 結論 很顯然,type 是 all,即最壞的情況。extra 裡還出現了 using filesort,也是最壞的情況。優化是必須的...
mysql單錶容量 MySQL單錶容量有多少
mysql單錶容量在500萬左右,效能處於最佳狀態,此時mysql的btree索引樹高在3到5之間 而單錶最大限已經不再由mysql限制了,改為電腦容量限制了。mysql單錶容量 mysql 單錶容量在500萬左右,效能處於最佳狀態,此時,mysql 的 btree 索引樹高在3 5之間。mysql...