速度:将聚合值存储在数据库中或使用Jinja进行计算?

时间:2016-12-11 13:56:18

标签: python database sqlite jinja2 flask-sqlalchemy

语言:Python

数据库:SQLite

使用:Flask,SQLAlchemy ORM

我的问题本身可能是一种矫枉过正,但我​​非常好奇。

我在SQLAlchemy Table中有一些列,它们包含我需要执行数学运算的某些值,以显示聚合值或计算值。

让我们假设:

第1列:0

第2栏:5

第3栏:2

第4栏:6

在HTML表格中,我需要依赖这些值来计算和显示算术运算的结果。

示例:(Column 1 + Column 2 + Column 3 / Column 6)* 100

我是否计算这些数字并将它们存储在我的SQLite数据库的新列中(使用SQLAlchemy),或者使用Jinja2动态计算它们?

1 个答案:

答案 0 :(得分:1)

对于任何优化问题,实际上没有单一的校正解决方案。您必须通过测试找出最佳解决方案。您的情况是时间(速度)的优化,因此我们应该查看内存(权衡)或如何持久和访问数据。以下是数据通过的图层:

磁盘 - > SQLite驱动程序 - > Python SQLite DBAPI - > SQLAlchemy - >金贾

排除磁盘(因为您选择的数据库在处理物理存储优化时并没有真正的技巧 - 毕竟它是单个文件)并且不包括DBAPI层(它的优点是与SQLAlchemy集成,您在SQLite的DBAPI驱动程序之间没有多少选择),这里有可能的方法来计算每一层中的列:

  1. SQLite驱动程序 - 您可以在SQLite中create a view获取计算列

    • 上层可以看到一个视图,好像它是一个表
    • 可以更改上层,但保持相同的定义
    • 无法通过删除和重新创建视图来动态修改计算
    • 无法memoize计算
    • 视图是只读的 - 在它周围构建一个ORM包装器毫无意义
    CREATE VIEW view_name (
        column_1,
        column_2,
        column_3_you_can_rename_columns_here,
        column_6,
        column_X)
    AS SELECT
        column_1,
        column_2,
        column_3,
        column_6,
        (column_1 + column_2 + column_3 / column_6) * 100.0
    FROM table_name
    
  2. SQAlchemy - 可以将计算列添加到Table类定义

  3. Jinja - 也可以在Jinja进行计算

    • 在此图层完成的计算不容易传递到以前的图层 - 难以持久保存到数据库
    • 可能不是最有效率的
  4. 根据经验,您通常会在数据库级别预先计算得到最佳结果,因为计算是在数据从一次传递中从磁盘提取到内存时完成的。但是,您选择的数据库限制了您在Python级别进行优化的选项。您需要使用timeit来测试哪种方法最适合您的用例。

    除非您的数据(输入列)具有经常重复的值,否则记忆可能对您没有帮助。请注意premature optimization is the root of all evil