设计 mySql 索引和主键以提高效率

Posted

技术标签:

【中文标题】设计 mySql 索引和主键以提高效率【英文标题】:designing mySql index and primary keying for efficiency 【发布时间】:2009-11-27 12:49:07 【问题描述】:

我有一个中等规模的记录集合——大约 2000 万条——我需要将它们加载到 mysql 中以用于数据分析。这些恰好是人们访问地方的记录。它们由三个数据项唯一标识:

地点 - 一个独特的 INT person - 一个字符串,有时是数字,有时是字母数字,例如 AB12345678 访问 - 与人相似

我无法控制人和访问字段的内容,因为这些是由不同的地方提供的,每个地方都有自己的事情。

我可以通过匹配地点和人来找到一个人的所有记录,并通过匹配所有三个来找到个人记录。

我可以通过创建这样的表在 mySql 中正常工作:

CREATE TABLE ENCOUNTER (
  PLACE int(11) NOT NULL,
  PERSON varchar(255) NOT NULL,
  VISIT varchar(255) NOT NULL,
  ARRIVAL_TIME datetime DEFAULT NULL,
  DEPARTURE_TIME datetime DEFAULT NULL,
  EVENT varchar(255) NOT NULL,
  PRIMARY KEY (PLACE,PERSON,VISIT)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;

我选择了 MyISAM,因为我不需要此表上的 ACID 事务完整性;它用于统计报告,所以如果它是一两行陈旧的,那没问题。

该表经常会受到仅更改其中一个字段的更新的影响,例如 DEPARTURE_TIME。这些 UPDATE 的频率很可能是新行 INSERT 的两倍。无需更新地点、人员或访问标识符。

这里有一些问题:

使用单个索引和键列连接地点/人员/访问信息是否会更好地提高性能?

我对 varchar 索引有多大的影响?是否值得尝试将它们限制为固定长度的字段?

收集的智慧有什么其他建议吗?

谢谢。

【问题讨论】:

【参考方案1】:

您的索引是正确的。你不会做得比这更好。

这是一个完美的、不明显的使用分区的机会。我有一种感觉,你所有的分析都将基于地点。如果是,则根据 place 列创建一个哈希分区,如下所示:

ALTER TABLE encounter PARTITION BY KEY(place) PARTITIONS 12;

这将使您的查询速度更快,因为 mysql 知道在对一个位置进行分析时它可以跳过查看 1/12 的行。

【讨论】:

谢谢。实际上,大多数分析很可能基于我的架构中的时间戳之一。问题是,它们可以在行创建后更改。但是就地分区是个好主意。【参考方案2】:

我可以通过匹配地点和人来找到一个人的所有记录,并通过匹配所有三个来找到个人记录。

如果您要搜索一个人去过的所有地方,您需要在(person, place) 上创建一个附加索引。

我对 varchar 索引有多大影响?是否值得尝试将它们限制为固定长度的字段?

INTVARCHAR 记录的击键时间相同。

对于VARCHAR 字段,关键缺失的代价更高。

【讨论】:

感谢您提供此信息,Q!我无法搜索一个人去过的所有地方,因为每个地方都有自己的个人 ID。地点 = 医院 人员 = 医院分配的病历编号 就诊 = 医院分配的患者就诊标识符。

以上是关于设计 mySql 索引和主键以提高效率的主要内容,如果未能解决你的问题,请参考以下文章

mysql-索引

怎么提高数据库查询效率

合理优化数据库表结构提高项目执行效率[数据库设计]

mysql 高效率查询背景

MySQL索引

MySQL索引