使数千个SELECT查询更快

时间:2019-02-27 07:55:16

标签: mysql mariadb pymysql

情况

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

问题

我需要选择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

选择整个表,遍历光标和樱桃选择行。 .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:]

预期行为

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

我咨询了其他答案,包括this,但由于我只有阅读权限,因此无法使用它,因此无法创建另一个要联接的表。

那我怎样才能使选择更快?

2 个答案:

答案 0 :(得分:2)

临时表实现如下:

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

答案 1 :(得分:0)

由于@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秒内选择了7K行。

为了完整起见,并为了将来的读者,留在这里作为答案。