我已经为使用MySQL后端的Ruby on Rails中的一个客户开发了基于Web的销售点系统。这些人的发展速度如此之快,以至于他们每天在全公司范围内接近10,000笔交易。对于这个问题,我将使用事务表作为示例。目前,我将 transactions.status 存储为具有索引的varchar(255)字段中的字符串(即:'pending','completed','incomplete')。一开始,我试图通过不同的状态查找记录时很好,因为我不必担心这么多记录。随着时间的推移,使用查询分析器,我注意到性能已经恶化,并且varchar字段可以真正减慢查询速度超过数千次查找。我一直在考虑使用事务模型中的 STATUS CONSTANT 将这些varchar字段转换为基于整数的状态字段,如下所示:
class Transaction < ActiveRecord::Base
STATUS = { :incomplete => 0, :pending => 1, :completed => 2 }
def expensive_query_by_status(status)
self.find(:all,
:select => "id, cashier, total, status",
:condition => { :status => STATUS[status.to_sym] })
end
这是我最好的选择吗?你们有什么建议?我已经在各种查找字段上使用了正确的索引,并且 memcached 尽可能用于查询缓存。它们目前设置在3台服务器的分布式服务器环境中,其中1st用于应用,第2用于DB&amp;第3次用于缓存(全部在1个数据中心和同一VLAN上)。
答案 0 :(得分:1)
您是否尝试过代表性数据库的替代方案?从你给出的例子来看,我有点怀疑它会产生很大的不同,你看。如果只有三种状态,那么按状态查询可能会更好,而根本不使用索引。
假设“已完成”占您表的80% - 没有涉及其他索引列,如果使用索引,则需要更多读取。因此,随着表的增长,对该类型的查询几乎肯定会变慢。但是,“不完整”和“待定”查询可能仍会从索引中受益;它们只会随着这些状态的总行数的增加而受到影响。
在没有更多选择性标准的情况下,您多久看一次,完整和其他方面?你可以用一些(内部或外部)方式对表进行分区吗?例如,将已完成的事务存储在单独的表中,在它们到达最终(?)状态时将新事务移动到那里。我认为在MySQL 5.1中引入了内部数据库分区 - 查看documentation似乎RANGE分区可能是合适的。
所有这一切,我认为将状态存储为字符串可能会带来一些好处。除了存储和带宽方面的考虑之外,你不小心错误拼写整数,或者更好的是一个常数或符号。
答案 1 :(得分:0)
你可能想要开始限制你的搜索(如果你还没有这样做),#find(:all)
在这个规模上非常繁重。此外,您可能想要考虑一下您的事务模型正在寻求什么,因为它被转换为您的视图,并且可能急于加载那些以最小化对数据库的请求以获取额外信息。