经常更改的条目的最佳数据库架构

时间:2012-05-30 17:14:45

标签: mysql indexing schema

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

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

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

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

进行过滤

首先,我尝试使用2个表:一个用于类别,另一个用于事件。索引是category-name,category-status-name,category-date-name和category-date-status-name。 为此,列表,过滤和排序非常快,但插入,更新或删除条目非常慢。我也有锁定超时,因为重建索引需要花费太多时间。

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

下一次尝试将为最后订阅日期和计数器创建一个自己的表。但是,过滤此日期或对此日期进行排序的可能性呢?

最好有3个索引,如: category-name,category-date,category-status ,或者是我的解决方案,包含4个索引 category-name,category-status-name ,category-date-name和category-date-status-name 对MySQL来说更好?

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

是否有人提供了一些技巧,如何设计出支持上述场景的优质快速数据库架构?

1 个答案:

答案 0 :(得分:1)

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

我不认为我可以在没有具体细节的情况下提供任何其他确定的答案。我可以给你一些一般的建议。

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

对于非群集(辅助)索引,索引越大,在插入时必须重建的次数越多。可以执行插入直到页面填满,然后重建。再次,追加到索引的末尾就可以了。

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

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

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

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

过滤表单LIKE '%[word]%'不能使用索引,但过滤LIKE '[word]%'可以使用索引。

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

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

一些与绩效无关的警告:

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