设计 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 索引有多大影响?是否值得尝试将它们限制为固定长度的字段?
INT
和 VARCHAR
记录的击键时间相同。
对于VARCHAR
字段,关键缺失的代价更高。
【讨论】:
感谢您提供此信息,Q!我无法搜索一个人去过的所有地方,因为每个地方都有自己的个人 ID。地点 = 医院 人员 = 医院分配的病历编号 就诊 = 医院分配的患者就诊标识符。以上是关于设计 mySql 索引和主键以提高效率的主要内容,如果未能解决你的问题,请参考以下文章