나는 "SQL 방식"으로 서로를 비교하여 텍스트 파일을 많이 처리합니다.DBI :: CSV 구현 Sqlite를 기반으로
DBD::CSV
은 텍스트 테이블에 SQL 구문을 사용할 수 있으므로 분명히 시작하는 것이 좋습니다. 그러나 거대한 텍스트 파일을 다루므로 성능면에서 쓸데없는 DBD::CSV
을 만들었습니다.
그래서, 나는 csv 파일을 sqlite DB로 변환하는 모듈을 작성한 다음 재생할 수있는 DBI::sqlite
객체를 반환합니다. 문제는, 텍스트 파일을 sqlite 테이블로 변환하는 것이 매우 효율적이지 않다는 것입니다. 왜냐하면 펄로드에서 sqlite 명령 줄을 실행하여 CSV 파일을 빠르게로드 할 수 없기 때문입니다 (.load를 사용). 그래서 텍스트 테이블을 기반으로 커다란 Insert into
문자열을 만들고 실행해야합니다 (라인 단위로 라인 삽입은 성능 측면에서 매우 비효율적이므로 하나의 큰 삽입을 실행하는 것이 좋습니다). 나는 그것을 피하기 위해 기꺼이 csv를 sqlite에 perl을 사용하여로드하기위한 한 줄짜리 탐색기를 찾는다.
그리고 또 다른 한가지
, 내가 실행하기 위해 다음과 같은 기능을 사용하고 인쇄 멋지게 SQL 쿼리 : 이sub sql_command {
my ($self,$str) = @_;
my $s = $self->{_db}->prepare($str) or die $!;
$s->execute() or die $!;
my $table;
push @$table, [ map { defined $_ ? $_ : "undef" } @{$s->{'NAME'}}];
while(my $row = $s->fetch) {
push @$table, [ map{ defined $_ ? $_ : "undef" }@$row ];
}
box_format($table);
return box_format($table);;
}
sub box_format {
my $table = shift;
my $n_cols = scalar @{$table->[0]};
my $tb = Text::Table->new(\'| ', '', (\' | ','')x($n_cols-1), \' |+');
$tb->load(@$table);
my $rule = $tb->rule(qw/- +/);
my @rows = $tb->body();
return $rule, shift @rows, $rule, @rows, $rule
if @rows;
}
sql_command
하위 약 ~ 1 분 내 생각에, (6.5 MB 파일)을 실행하는 데 걸리는 내가 기대할 수있는 길은 길다. 누구든지보다 효율적인 솔루션을 가지고 있습니까?
감사합니다.
나는 단지 $ conn-> begin_work과 $ conn-> commit으로 같은 줄을 생각하고 있었다. SQLite는 커다란 인서트가있는 슬러그입니다. – charlesbridge
고마워요! 좋은 형식으로 쿼리를 효율적으로 인쇄하는 방법은 무엇입니까? – Mattan
@Mattan "인쇄 쿼리"란 무엇을 의미합니까? 새로 생성 된 데이터베이스에 대한 쿼리를 의미합니까? 다른 질문 같아. – Schwern