我想设计一个快速的数据库模式,它可以处理排序和过滤列,就像更新条目一样。
为此,我创建了以下场景:
对于所有测试,我使用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是更好的,因为每个条目具有相同的长度,因此跳转到索引中的特定位置而不是使用变量长度更快。你觉得怎么样?
是否有人提供了一些技巧,如何设计出支持上述场景的优质快速数据库架构?
答案 0 :(得分:1)
索引是固定长度的,因此CHAR vs VARCHAR对索引无关紧要,但它对表扫描很重要。
我不认为我可以在没有具体细节的情况下提供任何其他确定的答案。我可以给你一些一般的建议。
您应该避免插入聚簇索引(InnoDB主键或第一个唯一键)。聚簇索引通常与自动递增列一起使用,因此索引仅附加到中间,并且不会在中间插入任何内容。这样可以避免重建索引。
对于非群集(辅助)索引,索引越大,在插入时必须重建的次数越多。可以执行插入直到页面填满,然后重建。再次,追加到索引的末尾就可以了。
删除不会影响性能,因为索引仅标记为删除,并且在空闲时间内重建索引。
不应在基数较低的列上创建索引,因为MySQL不会使用它们。只应根据需要添加索引,每次都要权衡利弊。
多列索引较大(页面中的条目较少),需要更新更多条目。谨慎添加多列索引。
MyISAM更适合频繁读取,但由于锁争用(表锁),在多用户环境中频繁更新/插入会导致陷入困境。由于锁争用较少(行锁),InnoDB更适合多用户环境中的更新,但读取速度较慢(仍然需要行锁)。
过滤表单LIKE '%[word]%'
不能使用索引,但过滤LIKE '[word]%'
可以使用索引。
在频繁更新的系统上,索引对于选择要更新的记录和读取它们同样重要。索引越好,锁争用越少,因此性能越好,死锁越少。
JOIN越多,成本越高,查询越慢。 JOIN也不错,但是很多行(大结果集)的JOIN可能很慢。
一些与绩效无关的警告:
使用InnoDB,您应该准备好处理因死锁而导致的失败事务。