针对 SQLite 运行 10,000 个 SELECT 查询需要几个小时

问题描述 投票:0回答:1

我正在使用 Python 和

sqlite3
库对单个表运行大约 10,000 个 SELECT 查询。在我的配置不高但不旧的笔记本电脑上本地运行它需要六七个小时才能完成。我在字段上创建了复合索引,但这没有任何区别。这是表格和查询(该表格是 IP 地址的地理位置数据,“地址”是通过去掉句号而得到的整数):

CREATE TABLE ip2location (ip_from INT, ip_to INT, country_code VARCHAR(2), country_name VARCHAR(255), region_name VARCHAR(255), city_name VARCHAR(255));
CREATE INDEX `ix_ip_between` ON `ip2location`(`ip_from`, `ip_to`);

SELECT country_name, city_name FROM ip2location 
                    WHERE ip_from <= ? and ip_to >= ? 
                    AND country_name != '-';
query = "SELECT country_name, city_name FROM ip2location \
                    WHERE ip_from <= ? and ip_to >= ? \
                    AND country_name != '-';"
results = []
for ip in ips: 
    cur.execute(query, [ip, ip])
    result = cur.fetchone()
    if result:
        results.append(result)

我预计需要一段时间,但不会这么长。问题出在Python、SQLite还是我身上?谢谢。

python sqlite
1个回答
0
投票

只需按照 @panagiotis-kanavos 的建议在 sql 中运行一个查询,并在 python 代码中处理国家 ~ ip 关系。

query = "SELECT country_name, city_name FROM ip2location \
                    WHERE ip_from <= ? and ip_to >= ? \
                    AND country_name != '-';"

这里只需输入你原始ip列表中最小和最大的ip值(因为它的类型是int,所以它在你的ips中总是有一个最小和最大的值)。 完成此操作后,根据您的需要获取行或创建 pandas 数据框(实际上从您的示例代码来看,我不确定您想要什么,如果您只需要不同的城市名称,然后将其添加到 sql 中)

但是,存在 ip 大小非常大的风险,并且您会获得很多不需要的城市名称以及更宽的 ip 范围: 一种解决方案是在将它们返回到 python 代码中后进行过滤,另一种解决方案可能会在表 ip2location 中创建一个新列,该列存储 对的哈希值 hi。 有了该列,您可以直接在查询中使用“in (h1, h2, ... )”。

© www.soinside.com 2019 - 2024. All rights reserved.