【发布时间】:2020-11-23 17:55:58
【问题描述】:
我目前正在使用 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()
考虑到这些因素,是否可以加快查询速度?
【问题讨论】:
-
5 秒对于这种查询来说是很长的时间。您是否缺少
row1上的索引? -
我对 SQL 比较陌生,我没有设置这个数据库。我对索引不熟悉,但是我刚刚读到的内容,听起来很有希望,但是,在每次搜索中搜索更改的关键值,我在操作中没有提到并且会更正。我认为正因为如此,我不能以那种方式使用索引。如果我错了,请告诉我。立即更新 OP。
-
您说每次搜索的值都会发生变化。这并不排除使用索引,这是索引的目的;基于价值的访问。如果您实际上是指列名更改,那么您将需要动态 SQL。
-
真的吗?可能是我只是不明白如何使用 index.html 。我会进一步研究。列名肯定不会改变。我已经使用 tkinter 获取值框更新了操作。
-
考虑使用parameters,
psycopg2绝对支持和推荐。虽然在这里您检查用户输入中的整数,但稍后您可能会接受字符串输入,并且聪明的恶意用户可以Bobby Tables您的数据库!此外,使用上下文管理器with来读取 .sql 文件和 DRY-er(Don't R重复 Y我们自己) 用于使用已定义方法或循环的查询调用的代码。
标签: python sql postgresql psycopg2