首页 > 解决方案 > 加快 Python 脚本的 PSQL 查询

问题描述

我目前正在使用 Psycopg2 从 4 个不同的表中运行 4 个单独的 SQL 查询。数据本身需要根据我打算使用它的目的进行分离,这就是我这样做的原因。在我从中提取的 4 个 SQL 表中,有 3 个的行数不到 200 万行,而第 4 个的行数要大得多,接近 2400 万行。这是一个非常简单的语句,基本上:

SELECT row1, row2, row3, row4 FROM largetable WHERE row1 = {value};

它通常返回 10-20 个匹配的行。

我正在为我的同事设计一个应用程序来查找这些数据并通过 Tkinter 窗口(我将在 MCVE 之外)显示它。考虑到他们需要用它做什么,我需要它尽快填充。整个加载和填充运行大约 10 秒,其中大约 5-6 秒只花在这个 SQL 上。该脚本授予对数据库的只读访问权限,因此无法操作表。

这是我需要在我的 py 脚本中加速的部分的 MCVE。SQL 文件都遵循上面的简单大纲,但从不同的表中提取。我们可以说 query_d 是最大的。

import psycopg2
from config import config
import tkinter as tk
from tkinter import *
from tkinter.ttk import *
import tkinter.messagebox

def get_val():
    class GetValue(tk.Tk):
        def __init__(self):
            tk.Tk.__init__(self)
            self.label = tk.Label(text="Input Control")
            self.label.config(font=("Ariel", 24))
            self.entry = tk.Entry(self)
            self.entry.config(font=("Ariel",18),justify='center')
            self.button = tk.Button(self, text="Populate", 
            command=self.on_button)
            self.label.pack()
            self.entry.pack()
            self.button.pack(pady=5)
            self.bind("<Return>",self.on_button)
            self.bind("<KP_Enter>",self.on_button)
            self.entry.focus_force()

        def on_button(self, event=None):
            global val
            try:
                val = int(self.entry.get())
            except:
                tk.messagebox.showerror("Invalid Entry", "Entry must be a 
                number.")
            else:
                if control:
                    conn = None
                    try:
                        params = config()
                        conn = psycopg2.connect(**params)
                        cur = conn.cursor()
                        global value
                        value = {'value':value}

                        query_a = open("query_a.sql", "r")  
                        a = query_a.read()
                        a = a.format(**value)
                        cur.execute(a)
                        global response_a
                        response_a = cur.fetchall()
                        query_a.close()

                        query_b = open("query_b.sql", "r")  
                        b = query_b.read()
                        b = b.format(**value)
                        cur.execute(b)
                        global response_b
                        response_b = cur.fetchall()
                        query_b.close()

                        query_c = open("query_c.sql", "r")  
                        c = query_c.read()
                        c = c.format(**value)
                        cur.execute(c)
                        global response_c
                        response_c = cur.fetchall()
                        query_c.close()
                        
                        query_d = open("query_d.sql", "r")  
                        d = query_d.read()
                        d = d.format(**value)
                        cur.execute(d)
                        global response_d
                        response_d = cur.fetchall()
                        query_d.close()

                    finally:
                        if conn is not None:
                        conn.close()
    app = GetValue()
    app.mainloop()

if __name__ == '__main__':
    get_control()

考虑到这些因素,是否可以加快查询速度?

标签: pythonsqlpostgresqlpsycopg2

解决方案


根据@jordanm 和@Belayer,我为每个表添加了一个索引,并将速度从大约 7-8 秒提高到大约 0.12 秒。


推荐阅读