我在一家科技公司担任产品经理(具有坚实的SQL背景),该公司专门为ICU和麻醉开发患者数据管理系统。到目前为止,我们的客户群主要是中小型医院,比如说最多20张病床,每分钟产生数据,但现在有机会销售给大型/大学医院,大约200张重症监护病床连接到多种医疗设备(监视器,呼吸机,透析,注射泵),我们计划推出新一代产品。
问题:我们收到了很多关于性能不佳的客户电话,并且在即将到来的产品中不会变得更好。系统会随着时间而变慢。
对于大客户,我计算了200张床,平均每张床每分钟30排。假设占用率为75%,每年总计约24亿行。每年约有3000例患者。
到目前为止,我们将每个输入,无论其来源(设备或用户)和数据类型(数字,文本,引用,日期和日期范围)都存储在一个充满索引的表中。我们的开发人员喜欢这样。
我的计划是根据数据类型将数据分离到不同的表中,因为我的印象是索引将更有针对性,我也用竞争对手的数据库进行了验证,它们完全是这样做的。
应用程序查询是非常基本的,主要如下所示
SELECT parameter_id, date_time, value
FROM data_numeric
WHERE visit_id = :visit_id
AND parameter_id = :parameter_id -- e.g. the heart rate
AND date_time >= :from_date_time
AND date_time < :to_date_time
一次没有超过50行的大容量插入或更新。
有什么想法或经验,我们应该如何开始?在这种情况下,索引组织的表或其他概念(如分区)是否有帮助?
感谢你的帮助!
1条答案
按热度按时间9nvpjoqh1#
您应该考虑坚持使用一个大表和索引架构。该解决方案可能比拆分表和索引更快。也许你有一些棘手的实现问题,阻止你的索引扩展?
一个索引统治所有索引(理论上)
B树索引的性能呈几何增长。如果主行只有一个数据点,从单个大索引进行阅读将花费O(N))磁盘读取。现在,假设您将该大索引拆分为10个较小的索引。从一个较小的索引中阅读将花费O(n(N/10)),这将只为您节省保存一次读取。
现在想象一下同样的场景,但是有两个数据点要读取。对于单个索引,阅读两个数据点可能仍然需要O(N)磁盘读取。这是因为这两个值将紧挨着存储,可能在同一个数据库块中。相比之下,从两个较小的索引中阅读两个数据点,其成本为2 * O(N(N/10)),几乎是两倍。
更真实的例子
如果上面的运行时分析看起来太抽象,下面是一个更实际的示例,演示了大表和索引策略如何优于多个小表和索引策略。
下面的代码创建了240 M行的数值数据和2.4M行的字符串数据。(我的系统无法处理完整的2.4B行,所以我将其缩小到1/10。)正如您所期望的,数值上的2.4亿行索引大约是字符串值上的2.4亿行索引的100倍。但是从每个索引中阅读单行具有非常相似的性能:4个磁盘读取数字,3个磁盘读取字符串。
如果您要查找单次访视或床的所有EAV数据,则您将花费更多的时间阅读1%的数据索引,而不是花费阅读99%的数据索引。如果是这样的话,你最好把所有的东西都放在一个表和一个索引中。
在许多情况下,一个大索引优于多个小索引。也许这不适用于您-也许您的索引访问不是我所假设的。但至少值得一试。了解对数性能 * 应该 * 如何发生可能有助于您找到现有索引的问题。
DATA_NUMERIC的2.4亿行代码。BLEVEL+1 = 4次读取。
2.4M行STRING_NUMERIC的代码。BLEVEL+1 = 3次读取。