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】:使用包含与您的查询匹配的字段的附加索引。如果行组合是唯一的,则使用主索引。这些提供比二级索引更快的访问。 由于表是静态的 - 索引的数量不会影响性能(任何更新、删除和插入都需要更新表的每个索引)。
因此,为了更快地从此查询中检索,请创建second
和third
列的索引:
ALTER TABLE T ADD PRIMARY KEY (second, third);
【讨论】:
表已经有一个主键(第一,第二,第三)[见上表]。我还尝试添加一个额外的索引(第一,第二),但没有改善结果。 请原谅我 - 我的意思是第二列和第三列。答案更正。 index (first, second, third) 不能仅用于第二列和第三列的查询。通常顺序会有所不同。 该索引已经存在'SECONDARY'(参见上面的索引表)。我目前有一个 PRIMARY KEY(第一,第二,第三),一个涵盖(第二,第三)的索引,以及仅在第二列上的另一个索引。 我创建了一个额外的索引覆盖(第二,第三,计数),现在检索只需不到 1 秒。但是,我不明白为什么会这样。任何人都可以对此有所了解吗?以上是关于MySQL 静态表的最佳索引的主要内容,如果未能解决你的问题,请参考以下文章
夯实Mysql基础MySQL性能优化的21个最佳实践 和 mysql使用索引