使用唯一的多列索引 table 的最佳方法?
Best way to index a table with a unique multi-column?
我正在创建一个 table,它将使用 InnoDB 存储引擎在 MySQL 5.6 中存储大约 1 亿行。这个 table 将有一个外键 link 到另一个 table 大约有 500 万行。
当前Table结构:
`pid`: [Foreign key from another table]
`price`: [decimal(9,2)]
`date`: [date field]
并且每个 pid
对于 date
应该只有一条记录
在此 table 上创建索引的最佳方法是什么?
选项 #1: 在两个字段 pid
和 date
上创建主索引
选项 #2: 添加另一列 id
,其中 AUTO_INCREMENT 和 primary index
并在列 [=13= 上创建唯一索引] 和 date
或任何其他选项?
我将在此 table 上使用的唯一 select 查询是:
SELECT pid,price,date FROM table WHERE pid = 123
两种方法都可以。我更喜欢使用合成主键(即具有附加唯一索引的自动递增版本)。我发现这很有用,原因如下:
- 您可以与 table 建立外键关系。
- 你有一个插入顺序的指标。
- 您可以更改要求,因此如果某些
pid
允许每天两个值或每周只允许一个值,那么 table 可以支持它们。
也就是说,这样的列有额外的开销。当您访问数据时,此开销会增加 space 和少量时间。您的 table 相当大,因此您可能希望避免这种额外的工作。
我会尝试使用一个试图覆盖查询的索引,希望 MySQL 只需要访问索引才能获得结果集。
ALTER TABLE `table` ADD INDEX `pid_date_price` (`pid` , `date`, `price`);
或
ALTER TABLE `table` ADD INDEX `pid_price_date` (`pid` , `price`, `date`);
如果您认为将来可能需要 select 在 pid 和 date 上应用条件,请选择第一个;如果您认为条件最有可能在 pid 和 price 上应用,请选择第二个。
这样,索引就拥有查询所需的所有数据(pid、价格和日期)及其在右列 (pid) 的索引
顺便说一下,总是使用 EXPLAIN 来查看查询规划器是否真的会使用整个索引(看看 key 和 keylen 输出)
根据您所说的(100M;唯一的查询是...;InnoDB;等):
PRIMARY KEY(pid, date);
并且没有其他索引
一些注意事项:
- 因为它是 InnoDB,所有其余字段都是 "clustered" 与 PK,因此通过 pid 进行查找就像
price
是 PK 的一部分一样。另外 WHERE pid=123 ORDER BY date
会非常有效。
- 不需要 INDEX(pid, date, price)
- 添加
AUTO_INCREMENT
没有任何好处(除了提示排序)。如果您需要 排序,那么索引 starting with date
可能是最好的。
- 额外的索引会减慢插入速度。特别是
UNIQUE
个。
我正在创建一个 table,它将使用 InnoDB 存储引擎在 MySQL 5.6 中存储大约 1 亿行。这个 table 将有一个外键 link 到另一个 table 大约有 500 万行。
当前Table结构:
`pid`: [Foreign key from another table]
`price`: [decimal(9,2)]
`date`: [date field]
并且每个 pid
对于 date
在此 table 上创建索引的最佳方法是什么?
选项 #1: 在两个字段 pid
和 date
选项 #2: 添加另一列 id
,其中 AUTO_INCREMENT 和 primary index
并在列 [=13= 上创建唯一索引] 和 date
或任何其他选项?
我将在此 table 上使用的唯一 select 查询是:
SELECT pid,price,date FROM table WHERE pid = 123
两种方法都可以。我更喜欢使用合成主键(即具有附加唯一索引的自动递增版本)。我发现这很有用,原因如下:
- 您可以与 table 建立外键关系。
- 你有一个插入顺序的指标。
- 您可以更改要求,因此如果某些
pid
允许每天两个值或每周只允许一个值,那么 table 可以支持它们。
也就是说,这样的列有额外的开销。当您访问数据时,此开销会增加 space 和少量时间。您的 table 相当大,因此您可能希望避免这种额外的工作。
我会尝试使用一个试图覆盖查询的索引,希望 MySQL 只需要访问索引才能获得结果集。
ALTER TABLE `table` ADD INDEX `pid_date_price` (`pid` , `date`, `price`);
或
ALTER TABLE `table` ADD INDEX `pid_price_date` (`pid` , `price`, `date`);
如果您认为将来可能需要 select 在 pid 和 date 上应用条件,请选择第一个;如果您认为条件最有可能在 pid 和 price 上应用,请选择第二个。
这样,索引就拥有查询所需的所有数据(pid、价格和日期)及其在右列 (pid) 的索引
顺便说一下,总是使用 EXPLAIN 来查看查询规划器是否真的会使用整个索引(看看 key 和 keylen 输出)
根据您所说的(100M;唯一的查询是...;InnoDB;等):
PRIMARY KEY(pid, date);
并且没有其他索引
一些注意事项:
- 因为它是 InnoDB,所有其余字段都是 "clustered" 与 PK,因此通过 pid 进行查找就像
price
是 PK 的一部分一样。另外WHERE pid=123 ORDER BY date
会非常有效。 - 不需要 INDEX(pid, date, price)
- 添加
AUTO_INCREMENT
没有任何好处(除了提示排序)。如果您需要 排序,那么索引 starting withdate
可能是最好的。 - 额外的索引会减慢插入速度。特别是
UNIQUE
个。