MySQL table 上的指数选择

Choice of indices on a MySQL table

我有以下 MySQL table:

CREATE TABLE example (
  id INT AUTO_INCREMENT NOT NULL,
  node0 SMALLINT DEFAULT 0 NOT NULL,
  node1 SMALLINT DEFAULT 0 NOT NULL,
  node2 SMALLINT DEFAULT 0 NOT NULL,
  node3 SMALLINT DEFAULT 0 NOT NULL,
  version SMALLINT DEFAULT 1 NOT NULL,
  user_id INT DEFAULT NULL,
  score INT DEFAULT 0 NOT NULL,
  datetime BIGINT NOT NULL,
  INDEX IDX_22B017FAA76ED395 (user_id), PRIMARY KEY(id)
)

ALTER TABLE example ADD CONSTRAINT FK_22B017FAA76ED395 FOREIGN KEY (user_id) REFERENCES user (id);

table 将相当大(-ish)(几百万个条目),我想知道为性能索引列的最佳方式是什么。

主要查询table,获取所有匹配的行:

...使用 Join 语句获取关联用户(user_id 字段)

这些字段(node0, node1, node2, node3, version) 可以形成一个键(所有这些字段的两行不能具有相同的值),但我想将ID保留为自动递增钥匙,这样我就可以订购它们了。

我应该为这些字段添加辅助键吗?或者将它们作为主键并将 ID 作为辅助键? And/or 添加单个索引?

您可能希望 multicolumn indexes 匹配您最常见的查询模式。我猜你说你的查询模式是这样的。

WHERE node0 = #constant# 
  AND node1 = #constant#
  AND node2 = #constant#
  AND node3 = #constant#
  AND version = #constant#

这个多列索引会有所帮助。

INDEX example_nodes_version (node0, node1, node2, node3, version)

如果您不按顺序过滤这些条件,它将无用。例如,它会帮助这个

WHERE node0 = #constant# 
  AND node1 = #constant#

但不是这个

WHERE node2 = #constant#
  AND version = #constant#

如果您的绝大多数查询都遵循第一个查询模式,这里有一种处理索引的更快方法。

您可以使主键成为这些列的串联,并创建一个 UNIQUE 键来处理您的自动递增 ID。

CREATE TABLE example (
  id INT AUTO_INCREMENT NOT NULL,
  node0 SMALLINT DEFAULT 0 NOT NULL,
  node1 SMALLINT DEFAULT 0 NOT NULL,
  node2 SMALLINT DEFAULT 0 NOT NULL,
  node3 SMALLINT DEFAULT 0 NOT NULL,
  version SMALLINT DEFAULT 1 NOT NULL,
  user_id INT DEFAULT NULL,
  score INT DEFAULT 0 NOT NULL,
  datetime BIGINT NOT NULL,
  INDEX IDX_22B017FAA76ED395 (user_id), 
  PRIMARY KEY(node0, node1, node2, node3, version),
  UNIQUE INDEX ex_autoincrement (id)
)

为什么这有帮助? InnoDB 使用 clustered index storage scheme。也就是说,它将所有数据存储为其主键的一部分。因此,根据上面的过滤进行查找将直接访问您的数据,而不必搜索索引,然后搜索单独的 table.

除非您预计这个 table 很大(一百万行或更多)并且被大量查询,否则您应该保持简单:创建索引以匹配您的查询模式并使用 id 作为主键。

并且知道这一点:随着应用程序及其 table 的增长,通常需要新的索引来匹配真实世界的查询模式。根据经验添加新索引很容易。