我们目前正在努力提高我们网站的查询性能,核心分层数据结构有5个级别,每个类型有大约20个字段。
level1: rarely added, updated infrequently, ~ 100 children
level2: rarely added, updated fairly infrequently, ~ 200 children
level3: added often, updated fairly often, ~ 1-50 children (average ~10)
level4: added often, updated quite often, ~1-50 children (average <10)
level5: added often, updated often (a single item might update once a second)
我们有一个数据管道,可以执行所有这些更新和插入(即我们可以完全控制进入的数据)。
我们需要做的查询是:
fetch single items from a level + parents
fetch a slice of items across a level (either by PK, or sometimes filtering criteria)
fetch multiple items from level3 and parts of their children (usually by complex criteria)
fetch level3 and all children
我们从这个数据源中读了很多,每秒数百次。我们需要执行的所有查询都是已知和优化的,并且它们可以是当前的数据结构。
我们目前正在使用memcached后面的MySQL查询,并且只是进行额外的查询以获取子/父,我认为某种基于树或基于文档的数据库可能更适合。
我的问题是:为了提高读取性能,建模这些数据的最佳方法是什么?
答案 0 :(得分:1)
听起来您的数据属于OLAP(联机分析处理)数据库。您描述级别,切片和性能问题的方式似乎适用于OLAP。它可能很好(虽然不确定),但你需要一个不同的工具来提高性能。
我目前正在管理这样的系统。我们有一个标准的关系数据库用于输入,然后将相关数据复制到OLAP服务器进行报告。我们的组合是Microsoft SQL Server(输入,原始数据),Microsoft Analysis Services(预先计算然后存储分析数据以提高速度),以及Microsoft Excel / Access数据透视表和/或Tableau用于报告。
OLAP服务器: http://en.wikipedia.org/wiki/Comparison_of_OLAP_Servers
结合关系和OLAP: http://en.wikipedia.org/wiki/HOLAP
的Tableau: http://www.tableausoftware.com/
* Tableau是一款极好的产品,如果你的数据不是很大(甚至可以处理大量数据),它可能会取代OLAP服务器。它将根据需要制作本地副本以提高性能。我强烈建议你试试看。
如果我误解了你所遇到的问题,那么请务必忽略这个答案:\
更新:经过更多讨论后,对象数据库也可能是一个解决方案。您的数据本质上听起来是多维的,但我认为不同之处在于您是在进行分析聚合计算和检索(SUM,AVG),还是仅存储和获取分类或关系数据(购物车)物品,或家庭成员的朋友)。
ODBMS信息:http://en.wikipedia.org/wiki/Object_database
InterSystem的缓存是我所知道的一个对象数据库,根据您的说法,它听起来更合适。
http://www.intersystems.com/cache/
如果转换到其他系统不可行(完全可以理解),那么您可能需要查看规范化以及查询正在处理的数据类型,以便进一步提高速度。事实上,在跳转到不同类型的系统之前,这可能是一个很好的第一步(对不起,我没有早点到达这个系统)。
就我而言,我在MS SQL上知道,我们通过使用VARCHAR
字段来使用INTEGER
字段进行的切换使得INNER JOIN
字段在速度方面产生了巨大差异。文本数据是要处理的最昂贵的数据类型之一。例如,如果您有一个查询在文本字段上执行了大量INTEGER
s,您可能会考虑规范化到您使用链接到文本数据的VARCHAR
ID的位置。
高标准化的一个例子可能是使用人的名字或姓氏的身份证号码。大多数数据库设计直接存储这些名称并且不会尝试减少重复,但您可以规范化为Last Name和/或First Name拥有自己的表(或者一个表同时包含名字和姓氏的表)和ID每个唯一的名字。
在您的情况下,重点是数据的重复数据删除,但从INTEGER
切换到{{1}}之类的内容可能会带来巨大收益。我首先尝试使用单个字段,测量前后情况,然后从那里仔细做出决定。
当然,一般来说,您应该确保对数据有适当的索引。
希望有所帮助。
答案 1 :(得分:1)
基于文档/树的数据库旨在执行分层查询。您的设计中是否有任何分层查询 - 我看不到任何问题?上下查询一个级别并不重要:它是一个简单的连接。请记住,进入“基于文档/树的数据库”路线会损害您的一般查询能力。总而言之,只需聘请一位能够分析您的绩效瓶颈的合格数据库专家 - 他们通常会在添加普通指数的情况下进行治疗。
答案 2 :(得分:1)
这里没有足够的信息可以说非常有用 - 你需要衡量一些事情,看看“解释”等等 - 但是超出通常索引的一个选项是按3级实例进行分片。这样可以在最简单的(单独的磁盘)上为不同分片的并行查询提供更好的性能,或者如果你想在每个分片上投入更多的资源,你可以使用不同的机器。
我提到这个的唯一原因是你的用例建议在这个级别进行分片会很好用(看起来在你的应用程序层中做起来很简单,如果你想 - 我不知道什么工具mysql就此而已。)
如果你的数据量不是那么高,那么使用分片你可能会把它归结为ssds ......