【问题标题】:Performance of a sql query on an indexed key vs primary key对索引键与主键的 sql 查询性能
【发布时间】:2013-04-09 21:15:18
【问题描述】:

我有一个 mysql innodb 表 -

create table data (
    `sha256` CHAR(64) NOT NULL,
    'created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    <some other fields>
    PRIMARY KEY (`sha256`),
)

mysqld_slow_query 中最慢的查询之一是

select * from data where created between "2013-02-01" and "2013-03-01";

为了改进这个查询的执行,我有两个选择:

选项 1:在创建时添加索引

选项 2:将 ('created', 'sha256') 设为主键,并在 sha256 上添加索引。

这里的想法是,当我们选择大量行时,比如一个月收集的数据,我想减少访问的 B-tree 块的数量。如果我们通过索引(选项 1)访问这些记录,我们最终仍然可能会访问每个记录的不同块。相反,如果我们将按时间戳排序的记录存储为主键/聚集键(选项 2),我们将在同一个 B-tree 块中找到大量记录,这将减少磁盘读取。

但由于某种原因,虽然选项 1 提高了性能,但选项 2 并没有提高多少。 任何想法为什么?还有其他建议吗?提前致谢。

【问题讨论】:

  • 这是 MyISAM 还是 InnoDB 表?
  • mysql什么时候允许你在CREATE TABLE命令中使用{
  • @G_Nugget InnoDB。 Barmar 修正了括号
  • @fvu 我认为问题不在于无关字段的索引,而是关于在created 上放置索引而不是使(created, sha256) 成为主键。
  • created 上添加索引肯定会大大加快查询速度。第二个选项对我来说没有任何意义。

标签: mysql sql


【解决方案1】:

InnoDB 对大主键特别敏感,因为它使用聚集主索引,而CHAR(64) 会产生非常大的主键。我建议您添加一个AUTOINCREMENT id 列作为主键,并给sha256 一个唯一索引。那些以及created 上的索引应该有助于提高性能。在sha256 上的查找会稍微慢一些,但其他一切都会更快。插入也将更快,因为数据永远不需要被 sha256 的随机值移动。

我不完全确定为什么单个索引会快得多,但这可能与复合索引太大有关,即使它是一个聚集索引。

【讨论】:

  • 是的,我知道主键 CHAR(64) 是个坏主意,在此期间,我会使用 HEX 或 char(64) 的子集。但这是一个单独的问题。问题是 - 为什么索引(created)比主键(created)更好,因为这个特定的查询会返回大量的行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
  • 1970-01-01
  • 2013-06-10
  • 2018-12-01
  • 1970-01-01
  • 2014-03-05
  • 2010-10-02
相关资源
最近更新 更多