mysql 單 索引 mysql 單錶索引優化

2021-10-17 16:01:34 字數 4526 閱讀 2129

建表語句

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...