【问题标题】:Need advice on how to index and optimize a specific MySQL database需要有关如何索引和优化特定 MySQL 数据库的建议
【发布时间】:2014-10-20 22:16:37
【问题描述】:

我正在尝试优化我的 MySQL 数据库,以便尽快查询它。

是这样的:

我的数据库由 1 个表组成,该表(目前)大约有 1800 万行 - 并且增长迅速。 此表具有以下列 - idx、时间、tag_id、x、y、z。 没有任何列有任何空值。

'idx' 是一个 INT(11) 索引列,AI 和 PK。现在是升序排列。

'time' 是一个日期时间列。它也在上升。表中 50% 的“时间”值是不同的(其余的值可能最多出现两次或 3 次)。

'tag_id' 是一个 INT(11) 列。它没有以任何方式排序,并且有 30-100 个不同的可能 tag_id 值分布在整个数据库中。它也是另一个表的外键。

插入 - 每隔 2-3 秒就会向表中插入一个新行。 'idx' 由服务器 (AI) 计算。由于“时间”列表示插入行的时间,因此插入的每个新“时间”都将高于或等于前一行。所有其他列值没有任何顺序。

选择 - 这是一个典型查询的示例: "select x, y, z, time from table where date(time) between '2014-08-01' and '2014-10-01' and tag_id = 123456"

因此,'time' 和 'tag_id' 是唯一出现在 where 部分的列,并且它们都将始终出现在每个查询的 where 部分中。 'x'、'y' 和 'z' 和 'time' 将始终出现在选择部分中。 'tag_id' 有时也可能出现在选择部分中。

查询通常会寻找更高(最近)的时间,而不是更早的时间。含义 - 表中后面的行将被更多地搜索。

索引- 现在,作为 PK 的 'idx' 是聚集的 ASC 索引。 'time' 也有一个非聚集的 ASC 索引。

就是这样。考虑到所有这些数据,一个典型的查询将在大约 30 秒内为我返回结果。这次我试图降低。有什么建议吗??

我正在考虑将一个或两个索引从 ASC 更改为 DESC(因为较高的值在搜索中更受欢迎)。如果我将 'idx' 更改为 DESC,它将在物理上反转整个表。如果我将“时间”更改为 DESC,它将反转“时间”索引树。但由于这是一个 1800 万行的表,这样的更改对于服务器来说可能需要很长时间,所以我想确定这是一个好主意。问题是,如果我颠倒顺序并插入新行,服务器会知道快速将其放在表的开头吗?还是会每次都在桌子上搜索这个地方?在表的开头放置一个新行是否意味着每次都需要对整个表进行某种数据转移?

或者也许我只是需要一种不同的索引技术? 非常欢迎您提出任何想法.. 谢谢!!

【问题讨论】:

标签: mysql indexing query-optimization


【解决方案1】:
select x, y, z, time from table 
where date(time) between '2014-08-01' and '2014-10-01' and tag_id = 123456

将列放在像date(time) 这样的函数调用中会破坏为该列使用索引的任何机会。如果要使用索引,则必须仅使用裸列进行比较。

因此,如果要将其与日期进行比较,则应存储 DATE 列。如果您有DATETIME 列,您可能必须使用这样的搜索词:

WHERE `time` >= '2014-08-01 00:00:00 AND `time` < '2014-10-02 00:00:00' ...

此外,您应该尽可能使用多列索引。首先放置在相等条件中使用的列,然后在范围条件中使用一列。有关此规则的更多信息,请参阅我的演示文稿How to Design Indexes, Really

您还可以从添加不用于搜索的列中受益,以便查询可以仅从索引条目中检索列。将这些列放在用于搜索或排序的列之后。这称为仅索引查询。

所以对于这个查询,你的索引应该是:

ALTER TABLE `this_table` ADD INDEX (tag_id, `time`, x, y, z);

关于 ASC 与 DESC,语法支持不同方向索引的选项,但在 MySQL 中最流行的两个存储引擎 InnoDB 和 MyISAM 中,没有区别。任何一种排序方向都可以或多或少地使用任何一种类型的索引。

【讨论】:

  • 谢谢!!我会看看你的建议
  • 非常感谢比尔!我按照您所说的将 00:00:00 添加到时间查询中,并且效果很好!
  • 很高兴为您提供帮助!顺便说一句,在 StackOverflow 上,习惯上会为有用的答案点赞,或者检查“已接受的答案”按钮以获得最有帮助的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 2013-01-02
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
  • 2011-05-02
相关资源
最近更新 更多