我的数据库有大约 6 亿条我想查询的条目()。这个本地 dbSNP 仅包含 rsID 和基因组位置。我使用了:
import sqlite3
import gzip
import csv
rsid_db = sqlite3.connect('rsid.db')
rsid_cursor = rsid_db.cursor()
rsid_cursor.execute(
"""
CREATE TABLE rsids (
rsid TEXT,
chrom TEXT,
pos INTEGER,
ref TEXT,
alt TEXT
)
"""
)
with gzip.open('00-All.vcf.gz', 'rt') as vcf: # from https://ftp.ncbi.nih.gov/snp/organisms/human_9606/VCF/00-All.vcf.gz
reader = csv.reader(vcf, delimiter="\t")
i = 0
for row in reader:
if not ''.join(row).startswith('#'):
rsid_cursor.execute(
f"""
INSERT INTO rsids (rsid, chrom, pos, ref, alt)
VALUES ('{row[2]}', '{row[0]}', '{row[1]}', '{row[3]}', '{row[4]}');
"""
)
i += 1
if i % 1000000 == 0:
print(f'{i} entries written')
rsid_db.commit()
rsid_db.commit()
rsid_db.close()
我想查询多个 rsID 并获取它们的基因组位置和改变(查询并rsid
获取chrom
、pos
、ref
和)。一个条目如下所示:alt
rsid
安全标识符 | 铬 | 位置 | 参考 | 替代 |
---|---|---|---|---|
rs537152180 | 1 | 4002401 | 格 | A、C |
我查询使用:
import sqlite3
import pandas as pd
def query_rsid(rsid_list,
rsid_db_path='rsid.db'):
with sqlite3.connect(rsid_db_path) as rsid_db:
rsid_cursor = rsid_db.cursor()
rsid_cursor.execute(
f"""
SELECT * FROM rsids
WHERE rsid IN ('{"', '".join(rsid_list)}');
"""
)
query = rsid_cursor.fetchall()
return query
无论输入多少条,大约需要 1.5 分钟。有没有什么方法可以加快速度?
17
最佳答案
2
其他人建议将你的rsid
列定义为主键,或者在其上创建唯一索引。这是一个好主意。
另一件事: rsid IN ('dirty','great','list','of',items')
可以使用所谓的来获取结果。如果你的rsid_list
数据非常大,或者它提取的值在词汇上相差很大,那么将列表中的项目放入临时表中,然后执行以下操作可能会有所帮助
SELECT rsids.*
FROM rsids
JOIN temp_rsids_list ON rsids.rsid = temp_rsids_list.rsids
以获得更有效的查找。
我会像这样声明表格:
CREATE TABLE rsids (
rsid TEXT PRIMARY KEY COLLATE BINARY,
chrom TEXT,
pos INTEGER,
ref TEXT,
alt TEXT
) WITHOUT ROWID
COLLATE BINARY
是默认设置。但显示它仍然很有帮助,因为您事先知道您不希望在该列上使用不区分大小写的匹配。这会提醒您未来的自己和您的同事这一重要的优化。
WITHOUT ROWID
告诉 SQLite 将表组织为所谓的“聚集索引”,其中其他值与易于搜索的主键一起存储。
如果您可以将主键变为 INTEGER,那么从性能角度来说这是一个好主意。
1
-
好的,主键确实做到了。查询现在需要 0.0 秒(在 .ipynb 内测量,我知道它实际上不是 0.0 秒)。我
COLLATE BINARY
还没有添加,也没有删除它们rs
。谢谢大家的帮助 :)。
–
|
您可以在列上创建索引rsID
:
CREATE UNIQUE INDEX idx_rsid
ON rsids(rsid);
仅当值唯一UNIQUE
时才可使用关键字。正如您所述,这是您的主键,因此根据定义它是唯一的。rsid
rsid
2
-
1rsid 应该是唯一的: /… 。我目前正在尝试将其作为 PRIMARY KEY。
–
-
1我没有生成这些数据。这是一个现有的大型公开数据库。因此,我不确定它是否是主键,但我认为是的。
–
|
rsid
。–
SELECT *
?为什么要选择所有字段?–
–
–
–
|