在分析應用程序時,我發現SQLAlchemy編譯SQL是佔用應用程序大部分CPU時間的任務之一。我已經明確了綁定的參數,但是看起來SQLAlchemy只在需要執行時才編譯查詢。有沒有辦法讓SQLAlchemy預編譯查詢?
有沒有辦法讓它預編譯查詢,以便在執行之前只需要極少的工作來替換綁定的參數?
在分析應用程序時,我發現SQLAlchemy編譯SQL是佔用應用程序大部分CPU時間的任務之一。我已經明確了綁定的參數,但是看起來SQLAlchemy只在需要執行時才編譯查詢。有沒有辦法讓SQLAlchemy預編譯查詢?
有沒有辦法讓它預編譯查詢,以便在執行之前只需要極少的工作來替換綁定的參數?
有一種方法...種。我已經在模塊解析時間定義查詢:
class MyClass(object):
# This works (slow)
query = select(...).where(...).order_by('distance').limit(1)
...
@classmethod
def issue_query(cls, **params):
cls.engine.execute(cls.query, params)
但SQLAlchemy中只保留編譯MyClass.query只有當MyClass.issue_query被稱爲(它被稱爲每次)。我注意到,在定義了查詢爲text()
使得它非常快(120us VS 600us)...但str(query)
編譯查詢到幾乎是一個text()
的說法,所以我試着將其定義爲:
class MyClass(object):
# This doesn't work
query = text(str(select(...).where(...).order_by('distance').limit(1)))
...
@classmethod
def issue_query(cls, **params):
cls.engine.execute(cls.query, params)
但是,SQLAlchemy試圖理解order_by()
中的'distance'
,並將中的1
轉換爲綁定參數(即從查詢中刪除該值)。這可以解決一點點黑客:
class MyClass(object):
# This works (fast)
query = text(str(select(...).where(...).order_by(text('distance')).limit(text('1'))))
...
@classmethod
def issue_query(cls, **params):
cls.engine.execute(cls.query, params)
剛發現你不能以這種方式使用任何綁定參數。甚至沒有使用bindparam()。 –
你使用什麼數據庫? –
這可能會幫助你:http://stackoverflow.com/questions/4617291/how-do-i-get-a-raw-compiled-sql-query-from-a-sqlalchemy-expression – IanAuld
Simeon:PostgreSQL;伊恩:謝謝 –