当前位置: 首页 > 面试题库 >

如何配置由SQLAlchemy驱动的应用程序?

潘宪
2023-03-14
问题内容

有没有人对Python / SQLAlchemy应用进行性能分析?找到瓶颈和设计缺陷的最佳方法是什么?

我们有一个Python应用程序,其中数据库层由SQLAlchemy处理。该应用程序使用批处理设计,因此很多数据库请求是在有限的时间内顺序执行的。当前运行时间太长,因此需要一些优化。我们不使用ORM功能,数据库是PostgreSQL。


问题答案:

有时,仅是普通的SQL日志记录(通过python的日志记录模块或通过上的echo=True参数启用create_engine())就可以使您了解需要花费多长时间。例如,如果您在执行SQL操作后立即记录某些内容,则您会在日志中看到类似以下内容的内容:

17:37:48,325 INFO  [sqlalchemy.engine.base.Engine.0x...048c] SELECT ...
17:37:48,326 INFO  [sqlalchemy.engine.base.Engine.0x...048c] {<params>}
17:37:48,660 DEBUG [myapp.somemessage]

如果您myapp.somemessage在操作后立即登录,则知道完成SQL部分操作花费了334ms。

记录SQL还可以说明是否发出了数十/百个查询,而这些查询可以通过联接更好地组织成更少的查询。使用SQLAlchemy
ORM时,提供了“紧急加载”功能,可以部分(contains_eager())或完全(eagerload()eagerload_all())自动执行此活动,但是如果没有ORM,它仅意味着使用联接,以便可以将多个表的结果加载到一个结果集中而不是随着查询深度的增加而乘以查询数量(即r + r*r2 + r*r2*r3…)

如果日志记录表明单个查询花费的时间太长,则需要对数据库处理查询,通过网络发送结果,由DBAPI处理,最后由SQLAlchemy的结果集接收到的时间进行细分。和/或ORM层。这些阶段中的每一个阶段都可以根据具体情况呈现自己的瓶颈。

为此,您需要使用分析,例如cProfile或hotshot。这是我使用的装饰器:

import cProfile as profiler
import gc, pstats, time

def profile(fn):
    def wrapper(*args, **kw):
        elapsed, stat_loader, result = _profile("foo.txt", fn, *args, **kw)
        stats = stat_loader()
        stats.sort_stats('cumulative')
        stats.print_stats()
        # uncomment this to see who's calling what
        # stats.print_callers()
        return result
    return wrapper

def _profile(filename, fn, *args, **kw):
    load_stats = lambda: pstats.Stats(filename)
    gc.collect()

    began = time.time()
    profiler.runctx('result = fn(*args, **kw)', globals(), locals(),
                    filename=filename)
    ended = time.time()

    return ended - began, load_stats, locals()['result']

要分析一段代码,请将其放置在带有装饰器的函数中:

@profile
def go():
    return Session.query(FooClass).filter(FooClass.somevalue==8).all()
myfoos = go()

概要分析的输出可用于给出花费时间的想法。例如,如果您看到所有时间都用在上cursor.execute(),那是对数据库的低级DBAPI调用,这意味着应该通过添加索引或重组查询和/或基础架构来优化查询。对于该任务,我建议使用pgadmin及其图形化EXPLAIN实用程序,以查看查询正在执行的工作类型。

如果看到成千上万的与获取行有关的调用,则可能意味着查询返回的行比预期的多-由于联接不完全而导致的笛卡尔乘积会导致此问题。另一个问题是在类型处理上花费的时间-
一种SQLAlchemy类型,例如Unicode将对绑定参数和结果列执行字符串编码/解码,这并不是在所有情况下都需要的。

配置文件的输出可能有点令人生畏,但经过一些练习后,它们很容易阅读。邮件列表上曾经有人声称运行缓慢,在让他发布配置文件的结果后,我能够证明速度问题是由于网络延迟所致-
cursor.execute()以及所有Python中花费的时间方法非常快,而大部分时间都花在socket.receive()上。

如果您有雄心壮志,那么在http://www.sqlalchemy.org/trac/browser/sqlalchemy/trunk/test/aaa_profiling中,也可以在SQLAlchemy单元测试中找到更多涉及SQLAlchemy分析的示例。在那里,我们进行了使用装饰器的测试,该装饰器声明了用于特定操作的最大方法调用数,因此,如果检入效率低下的东西,测试将揭示该方法调用(请注意,在Python中,函数调用具有最高的任何操作的开销,并且调用次数通常与所花费的时间几乎不成比例)。值得注意的是“
zoomark”测试,它使用了一种奇特的“ SQL捕获”方案,该方案从等式中削减了DBAPI的开销-尽管该技术不是“



 类似资料:
  • 问题内容: 有没有人对Python / SQLAlchemy应用进行性能分析?找到瓶颈和设计缺陷的最佳方法是什么? 我们有一个Python应用程序,其中数据库层由SQLAlchemy处理。该应用程序使用批处理设计,因此许多数据库请求是在有限的时间内顺序执行的。当前运行时间太长,因此需要一些优化。我们不使用ORM功能,数据库是PostgreSQL。 问题答案: 有时,仅是普通的SQL日志记录(通过p

  • 每当我试图使用ODBC驱动程序访问MDB文件时,它都会给我一个错误: 因此,我决定使用UCanAccess JDBC驱动程序。

  • 问题内容: 据我所知,您只能使用VisualVM来分析正在运行的应用程序。 有谁知道使用VisualVM剖析Java应用程序启动和启动的方法吗? 我相信必须有一种方法,否则将是一个重大的疏忽。 希望我只是误读了文档。 谢谢,第 问题答案: 您是否要使用`-Xrunjdwp“命令行选项来设置性能分析?如果是,则该选项仅出于此目的具有” suspend“参数 : 如果要在加载主类之前立即挂起目标VM,

  • 问题内容: 我需要找到Android应用程序中的瓶颈所在。 我可以使用哪些配置文件工具或技术? 问题答案: 您可以使用Traceview。它远非理想,但可行。 本文介绍了如何使用它。

  • 问题内容: 我有一个如下所示的route.js: 考虑到我要创建200多种不同的路线,最终我会遇到诸如“ article1”,“ article2”等内容 而我的app.js就像: 有没有动态的方式来创建这个? 问题答案: 终于成功了。 在我遇到的情况下,第1条,第2条等: 在获得多级网址的情况下,我创建了一个自定义函数:

  • 我是卡桑德拉和莫文的新手。我试图在eclipse中编写一个简单的java程序,它使用cassandra java驱动程序连接到我设置的cassandra节点。我找到了这个存储库https://github.com/datastax/java-driver但我不知道该怎么处理它。有谁能给我一步一步的说明来获取驱动程序并创建一个使用驱动程序的简单eclipse项目吗。