【问题标题】:Best database schema for highly often changed entries经常更改条目的最佳数据库模式
【发布时间】:2012-06-04 23:16:54
【问题描述】:

我想设计一个快速的数据库架构,它可以像更新条目一样处理排序和过滤列。

为此,我创建了以下场景:

  • 一个事件只有一个名称、状态、最后订阅日期、描述和一个位置
  • 活动的可用席位数量与活动一起保存,并且每次参与者订阅时都会更新
  • 每个事件都只有一个类别
  • 事件只能按类别列出
  • 可以按名称、状态或日期过滤事件(无异或)
  • 事件可以按名称、状态或日期(异或)排序
  • 表必须处理超过 10 个 mio 条目

对于所有测试,我使用 MySQL 和 InnoDB 表。我还尝试尽可能频繁地使用多个插入/更新/删除。 过滤是通过使用 LIKE '%[word]%'

首先我尝试使用 2 个表:一个用于类别,另一个用于事件。索引是类别名称、类别状态名称、类别日期名称和类别日期状态名称。 为此,列出、过滤和排序非常快,但插入、更新或删除条目非常慢。我也遇到了锁超时,因为重建索引花费了太多时间。

第二次尝试是有 3 个表格:类别、事件和位置。 但是如果位置表包含 6 个或更多条目,它也会变慢。我认为是因为快速捕获的索引。添加 100k 个条目大约需要 272 秒。 locations 的索引是 primary-index idzip-street

下一个尝试是为 last-subscription-date 和计数器创建一个自己的表。但是过滤这个日期或排序这个日期的可能性呢?

最好有 3 个索引,例如:category-name、category-date、category-status 还是我使用 4 个索引的解决方案 category-name、category-status-name 、category-date-name 和 category-date-status-name 哪个更适合 MySQL?

我也在考虑字段类型:目前我使用 VARCHAR 作为名称。但也许 CHAR 更好,因为每个条目都具有相同的长度,因此跳转到索引中的特定位置而不是使用可变长度会更快。你怎么看?

有人对如何设计一个支持上述场景的良好和快速的数据库模式有一些建议吗?

【问题讨论】:

  • 索引是固定长度的,因此 CHAR 与 VARCHAR 对索引无关紧要,但对表扫描很重要。
  • 我不知道这个。谢谢你。我试图通过在所有相关列上添加索引来避免表扫描

标签: mysql indexing schema


【解决方案1】:

索引是固定长度的,因此 CHAR 与 VARCHAR 对索引无关紧要,但对表扫描很重要。

如果没有具体细节,我认为我无法提供任何其他明确的答案。我可以给你一些一般性的建议。

您应该避免插入聚集索引(InnoDB 主键或第一个唯一键)。聚集索引通常与自动递增的列一起使用,以便仅将索引附加到中间,而不会在中间插入任何内容。这样可以避免重建索引。

对于非聚集(二级)索引,索引越大,插入时重建的次数就越多。可以执行插入,直到页面填满,然后重新构建。同样,附加到索引的末尾也可以。

删除不会影响性能,因为索引只标记为删除,并且在空闲时间重建索引。

不应在基数较低的列上创建索引,因为 MySQL 不会使用它们。仅应根据需要添加索引,每次都权衡利弊。

多列索引更大(页面中的条目更少)并且需要更新更多条目。谨慎添加多列索引。

MyISAM 更适合频繁读取,但由于锁争用(表锁)而在多用户环境中频繁更新/插入会陷入困境。由于锁争用(行锁)较少,InnoDB 更适合多用户环境中的更新,但读取速度较慢(仍需要行锁)。

LIKE '%[word]%' 形式的过滤不能使用索引,但过滤LIKE '[word]%' 可以使用索引。

在频繁更新的系统上,索引对于选择记录进行更新和读取记录同样重要。索引越好,锁争用越少,因此性能越好,死锁越少。

JOIN 越多,成本越高,查询越慢。 JOIN 还不错,但是多行(大型结果集)上的 JOIN 可能会很慢。

一些与性能无关的警告:

使用 InnoDB,您应该准备好处理由于死锁而导致的失败事务。

【讨论】:

  • 如何避免插入带有主键的表的聚集索引?
  • 只有 InnoDB 有聚集索引。如果您必须经常插入自然主键,通常的解决方案是使用代理 auto_increment 主键,因此您总是追加到聚集索引的末尾而不是插入。
猜你喜欢
  • 1970-01-01
  • 2012-05-28
  • 2011-11-01
  • 2022-11-11
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 2015-08-29
  • 1970-01-01
相关资源
最近更新 更多