让成千上万的 SELECT 查询更快

Making thousands of SELECT queries faster

情况

问题

我需要 select IDX 在文本文件中的所有行。

我的努力

版本 1

进行 7K 次查询,文本文件中的每一行一个。每秒大约进行 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

Select 整个 table,遍历光标和 cherry-pick 行。 .fetchall_unbuffered() 上的 for 循环每秒涵盖 30-40K 行,整个脚本大约需要 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:]

预期行为

我需要select更快,因为文本文件中的 IDX 数量将来会增长到 10K-100K。

我参考了其他答案,包括this,但我无法使用它,因为我只有阅读权限,因此无法创建另一个table加入。

那么我怎样才能使 selection 更快?

临时 table 实现如下所示:

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")

感谢@danblack 的提示(或超过 提示),我能够通过以下查询获得所需的结果。

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

danblack 的 SELECT 语句对我不起作用,引发错误:

pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'IDX' at line 1")

这可能是因为MariaDB的join语法,所以查阅了MariaDB documentation on joining tables.

现在它在 0.9 秒内选择了 7K 行。

为了完整起见,留在这里作为答案,也是为了未来的读者。