【问题标题】:Best way to index a table with a unique multi-column?索引具有唯一多列的表的最佳方法?
【发布时间】:2015-09-30 11:18:11
【问题描述】:

我正在创建一个表,它将使用 InnoDB 存储引擎在 MySQL 5.6 中存储大约 1 亿行。该表将有一个外键链接到另一个包含大约 500 万行的表。

当前表结构:

`pid`: [Foreign key from another table]

`price`: [decimal(9,2)]

`date`: [date field]

每个pid 应该只有一个date 的记录

在此表上创建索引的最佳方法是什么?

选项 #1:piddate 两个字段上创建主索引

选项 #2: 使用 AUTO_INCREMENT 和 primary index 添加另一列 id,并在 piddate 列上创建唯一索引

或者有其他选择吗?

我将在此表上使用的唯一选择查询是:

SELECT pid,price,date FROM table WHERE pid = 123

【问题讨论】:

    标签: mysql database indexing innodb


    【解决方案1】:

    根据你所说的(100M;唯一的查询是...;InnoDB;等等):

    PRIMARY KEY(pid, date);
    

    没有其他索引

    一些注意事项:

    • 由于它是 InnoDB,所有其余字段都与 PK “聚集”在一起,因此通过 pid 查找就像 price 是 PK 的一部分一样。 WHERE pid=123 ORDER BY date 也会非常高效。
    • 不需要 INDEX(pid、日期、价格)
    • 添加AUTO_INCREMENT 没有任何好处(除了排序提示)。如果您需要排序,那么以date 开头的索引 可能是最好的。
    • 额外的索引会减慢插入速度。尤其是UNIQUE 的。

    【讨论】:

      【解决方案2】:

      任何一种方法都可以。我更喜欢使用合成主键(即具有附加唯一索引的自动递增版本)。我发现这很有用有几个原因:

      • 您可以与表建立外键关系。
      • 您有一个插入顺序指示器。
      • 您可以更改要求,因此如果某些pids 允许每天两个值或每周仅一个值,那么表格可以支持它们。

      也就是说,这样的列还有额外的开销。当您访问数据时,这种开销会增加空间和少量时间。您有一张相当大的桌子,因此您可能希望避免这种额外的工作。

      【讨论】:

      • 如果您要在索引中包含date,您不妨包含price。单独使用pid,或者所有三列。
      • 不,如果我创建一个三列唯一索引,我可能会得到同一日期的重复条目(因为同一天可能有两个不同的价格)。
      【解决方案3】:

      我会尝试使用试图覆盖查询的索引,希望 MySQL 必须访问索引才能获得结果集。

      ALTER TABLE `table` ADD INDEX `pid_date_price` (`pid` , `date`, `price`);
      

      ALTER TABLE `table` ADD INDEX `pid_price_date` (`pid` , `price`, `date`);
      

      如果您认为将来可能需要选择应用条件而不是 pid 和 date,请选择第一个;如果您认为条件最有可能超过 pid 和 price,请选择第二个。

      这样,索引具有查询所需的所有数据(pid、价格和日期)及其在右列 (pid) 上的索引

      顺便说一句,总是使用 EXPLAIN 来查看查询计划器是否真的会使用整个索引(看看 key 和 keylen 输出)

      【讨论】:

      • 如果我创建一个三列索引,你不认为它会减慢插入速度吗?
      • 当然,每增加一个索引都会减慢插入速度。这是瓶颈在哪里的问题。
      猜你喜欢
      • 2013-01-05
      • 1970-01-01
      • 2021-01-10
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      相关资源
      最近更新 更多