MySQL 静态表的最佳索引

Posted

技术标签:

【中文标题】MySQL 静态表的最佳索引【英文标题】:MySQL best index for static table 【发布时间】:2014-01-13 09:40:20 【问题描述】:

mysql中有如下表(T):

+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| first  | varchar(50) | NO   | PRI | NULL    |       |
| second | varchar(50) | NO   | PRI | NULL    |       |
| third  | varchar(50) | NO   | PRI | NULL    |       |
| count  | bigint(20)  | NO   |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+

此表包含数百万行。我创建了以下索引:

+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name  | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| T     |          0 | PRIMARY   |            1 | first       | A         |      591956 |     NULL | NULL   |      | BTREE      |         |               |
| T     |          0 | PRIMARY   |            2 | second      | A         |    67927032 |     NULL | NULL   |      | BTREE      |         |               |
| T     |          0 | PRIMARY   |            3 | third       | A         |   271708128 |     NULL | NULL   |      | BTREE      |         |               |
| T     |          1 | SECONDARY |            1 | second      | A         |      398399 |     NULL | NULL   |      | BTREE      |         |               |
| T     |          1 | SECONDARY |            2 | third       | A         |    45284688 |     NULL | NULL   |      | BTREE      |         |               |
| T     |          1 | SEC       |            1 | second      | A         |     4382389 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

搜索类型:

SELECT * FROM T WHERE first = "WHAT" AND third = "EVER";

SELECT * FROM T WHERE first = "WHAT" AND second = "EVER";

通常也很快(结果总是在 1 秒内获得)。但是搜索如下:

SELECT * FROM T WHERE second = "WHAT" AND third = "EVER";

非常慢(通常超过 1 分钟)。我创建了索引 SEC(参见索引表),但这并没有改善结果。

我应该使用什么索引来加快这些搜索速度? (我没有继续试验,因为创建一个索引大约需要 5 个小时)

更多信息:该表是静态的(即我不会再添加任何行 - 我只对搜索速度感兴趣),磁盘空间不是问题。

【问题讨论】:

【参考方案1】:

使用包含与您的查询匹配的字段的附加索引。如果行组合是唯一的,则使用主索引。这些提供比二级索引更快的访问。 由于表是静态的 - 索引的数量不会影响性能(任何更新、删除和插入都需要更新表的每个索引)。

因此,为了更快地从此查询中检索,请创建secondthird 列的索引:

ALTER TABLE T ADD PRIMARY KEY (second, third);

【讨论】:

表已经有一个主键(第一,第二,第三)[见上表]。我还尝试添加一个额外的索引(第一,第二),但没有改善结果。 请原谅我 - 我的意思是第二列和第三列。答案更正。 index (first, second, third) 不能仅用于第二列和第三列的查询。通常顺序会有所不同。 该索引已经存在'SECONDARY'(参见上面的索引表)。我目前有一个 PRIMARY KEY(第一,第二,第三),一个涵盖(第二,第三)的索引,以及仅在第二列上的另一个索引。 我创建了一个额外的索引覆盖(第二,第三,计数),现在检索只需不到 1 秒。但是,我不明白为什么会这样。任何人都可以对此有所了解吗?

以上是关于MySQL 静态表的最佳索引的主要内容,如果未能解决你的问题,请参考以下文章

阿里二面:MySQL索引是怎么支撑千万级表的快速查找?

夯实Mysql基础MySQL性能优化的21个最佳实践 和 mysql使用索引

MySQL索引是怎么支撑千万级表的快速查找(一.外存储器-磁盘)

MySQL--索引

MySQL数据库索引

MySQL索引的设计使用和优化