mariadb 加快数千个SELECT查询的速度

kmb7vmvb  于 2022-11-08  发布在  其他
关注(0)|答案(2)|浏览(334)

情况

  • 使用Python 3.7.2
  • 我读过一个服务器上有500万行的MariaDB表的权限。
  • 我有一个7 K整数的本地文本文件,每行一个整数。
  • 整数表示表的IDX。
  • 表的IDX列是主键。(所以我想它是自动索引的?)

问题

我需要选择IDX在文本文件中的所有行。
我的努力

版本1

进行7 K次查询,每一次查询对应于文本文件中的一行。这使得每秒大约进行130次查询,花费大约1分钟来完成。

import pymysql
connection = pymysql.connect(....)
with connection.cursor() as cursor:
    query = (
        "SELECT *"
        " FROM TABLE1"
        " WHERE IDX = %(idx)s;"
    )

    all_selected = {}
    with open("idx_list.txt", "r") as f:
        for idx in f:
            idx = idx.strip()
            if idx:
                idx = int(idx)
                parameters = {"idx": idx}
                cursor.execute(query, parameters)
                result = cursor.fetchall()[0]
                all_selected[idx] = result

版本2

选择整个表,遍历游标并挑选行,.fetchall_unbuffered()上的for循环每秒覆盖30- 40 K行,整个脚本大约需要3分钟才能完成。

import pymysql
connection = pymysql.connect(....)
with connection.cursor() as cursor:
    query = "SELECT * FROM TABLE1"

    set_of_idx = set()
    with open("idx_list.txt", "r") as f:
        for line in f:
            if line.strip():
                line = int(line.strip())
                set_of_idx.add(line)

    all_selected = {}
    cursor.execute(query)
    for row in cursor.fetchall_unbuffered():
        if row[0] in set_of_idx:
            all_selected[row[0]] = row[1:]

预期行为

我需要更快地选择,因为文本文件中的IDX数量将来会增长到10 K-100 K。
我参考了其他答案,包括this,但我不能使用它,因为我只读过previilege,因此不可能创建另一个表来连接。
那么,如何才能使选择更快?

hgtggwj0

hgtggwj01#

临时表的实现如下所示:

connection = pymysql.connect(....,local_infile=True)
with connection.cursor() as cursor:
    cursor.execute("CREATE TEMPORARY TABLE R (IDX INT PRIMARY KEY)")
    cursor.execute("LOAD DATA LOCAL INFILE 'idx_list.txt' INTO R")
    cursor.execute("SELECT TABLE1.* FROM TABLE1 JOIN R USING ( IDX )")
    ..
    cursor.execute("DROP TEMPORARY TABLE R")
cqoc49vn

cqoc49vn2#

多亏了@danblack的提示(或者不止一个 * 提示 *),我才能用下面的查询获得想要的结果。

query = (
    "SELECT *"
    " FROM TABLE1"
    " INNER JOIN R"
    " ON R.IDX = TABLE1.IDX;"
)
cursor.execute(query)

danblack的SELECT语句对我不起作用,引发了一个错误:
pymysql.err.ProgrammingError:(1064,“您的SQL语法中有错误;请查看与您的MariaDB服务器版本对应的手册,以了解在第1行“IDX”附近使用的正确语法”)
这可能是因为MariaDB的连接语法,所以我参考了MariaDB documentation on joining tables
现在,它在0.9秒内选择7 K行。
为了完整起见,也为了将来的读者,在这里作为一个答案离开。

相关问题