如何加快解析40Gb txt文件并在sqlite数据库中每行插入一行的过程



背景

我目前正在尝试解析一个.txt.com区域文件。它的结构是这样的

blahblah.com    xx     xx      examplens.com

目前我的代码的结构是这样的

extern crate regex;
use regex::Regex;
use rusqlite::{params, Connection, Result};

#[derive(Debug)]
struct Domain {
id: i32,
domain: String,
}
use std::io::stdin;
fn main() -> std::io::Result<()> {

let mut reader = my_reader::BufReader::open("data/com_practice.txt")?;
let mut buffer = String::new();
let conn: Connection = Connection::open("/Users/alex/Projects/domain_randomizer/data/domains.db").unwrap();

while let Some(line) = reader.read_line(&mut buffer) {
let regexed_i_think = rexeginton_the_domain_only(line?.trim());
println!("{:?}", regexed_i_think);
sqliting(regexed_i_think, &conn).unwrap();
}

let mut stmt = conn.prepare("SELECT id, domain FROM domains").unwrap();
let domain_iter = stmt.query_map(params![], |row| {
Ok(Domain {
id: row.get(0)?,
domain: row.get(1)?,
})
}).unwrap();
for domain in domain_iter {
println!("Found person {:?}", domain.unwrap());
}
Ok(())
}
pub fn sqliting(domain_name: &str, conn: &Connection) -> Result<()> {
let yeah = Domain {
id: 0,
domain: domain_name.to_string()
};
conn.execute(
"INSERT INTO domains (domain) VALUES (?1)",
params![yeah.domain],
)?;
Ok(())
}
mod my_reader {
use std::{
fs::File,
io::{self, prelude::*},
};
pub struct BufReader {
reader: io::BufReader<File>,
}
impl BufReader {
pub fn open(path: impl AsRef<std::path::Path>) -> io::Result<Self> {
let file = File::open(path)?;
let reader = io::BufReader::new(file);
Ok(Self { reader })
}
pub fn read_line<'buf>(
&mut self,
buffer: &'buf mut String,
) -> Option<io::Result<&'buf mut String>> {
buffer.clear();
self.reader
.read_line(buffer)
.map(|u| if u == 0 { None } else { Some(buffer) })
.transpose()
}
}
}
pub fn rexeginton_the_domain_only(full_line: &str) -> &str {
let regex_str = Regex::new(r"(?m).*?.com").unwrap();
let final_str = regex_str.captures(full_line).unwrap().get(0).unwrap().as_str();
return final_str;
}

问题

所以我每次分析一个域,每次都插入一个。正如我所收集到的,如果我在一个事务中进行数千次插入,那么插入的效率会高得多。然而,我不太确定围绕这一点重构解析的有效方法是什么。

问题

我应该如何围绕插入过程调整解析过程?此外,我如何首先积极衡量流程的速度和效率,以便以清晰的方式进行比较和对比?

  1. 使用journal_mode=WAL打开数据库,如果不需要持久性,则使用synchronous=off
  2. 创建事务
  3. 创建准备好的语句
  4. 重复execute准备好的语句

作为健全性检查,您还可以评测您的程序,看看sqlite是瓶颈的假设是否正确。

最新更新