2011-03-30 3 views
0

이 DBI prepare 문을 최적화하기 위해이 코드를 조정할 때 Perl 도움이 필요합니다. 나는 이것을 더 최적화 할 수 있다고 확신한다. 나는 내가이 연결을 제대로 가지고 있다고 생각 하나, 나는 한 번 쿼리를 파싱하고 유일하게 (1) 매개 변수의 변경으로 바꾸고 싶다. 나는 그걸 어떻게 준비해야할지 모르겠다.준비된 명령문에서 tablename 자리 표시자를 어떻게 사용합니까?

기본적으로 테이블 목록을 가져 와서 단일 쿼리의 입력으로 테이블을 반복합니다. 기본적으로 이것은 다른 테이블 이름을 가진 동일한 쿼리입니다.

누군가 내가 이것을 최적화 할 수있는 방법을 보여줄 수 있습니까?

my @tbls = qx(mysql -u foo -pf00 --database $dbsrc -h $node --port 3306 -ss -e "show tables"); 
my $dbh = DBI->connect("DBI:mysql:database=$dbsrc;host=$node;port=3306",'foo','f00'); 

# Creating a logfile 
open (MYLOG, ">$dmpdir$node-mytstdmp-$dt.log") || die "cannot append"; 

# Loop through each table and create its own data file 
foreach my $tbls (@tbls) 
{ 
    chomp $tbls; 
    print MYLOG "START Time ==> ", &dt2, "\n"; 
    extract_data($dbh, $tbls); 
    print MYLOG "TIME END ==> ", &dt2, "\n"; 
}; 
$dbh->disconnect; 
close (MYLOG); 

sub extract_data 
{ 
    my($dbh, $tbls) = @_; 
    my $out_file = "$dmpdir$node-$tbls.$dt.out"; 
    open (my $gzip_fh, "| /bin/gzip -c > $out_file.gz") or die "error starting gzip $!"; 
    print MYLOG "Creating dmp file ==> $out_file.gz\n"; 
    my $sth = $dbh->prepare("SELECT UUID(), '$node', 1, 2, flg, upd, vts FROM $tbls"); 
    $sth->execute(); 
    while (my($uid, $hostnm,$1,$2,$flg,$upd,$vts) = $sth->fetchrow_array()) { 
     print $gzip_fh "_key_$uid^Ehost^A$hostnm^E1^A$1^E2^A$2^Eflg^A$flg^Eupd^A$upd^Evts^A$vts^D"; 
    } 
    $sth->finish; 
    close $gzip_fh or die "Failed to close file: $!"; 
}; 

답변

2

NYTProf 같은 프로파일 러를 통해 코드를 실행

여기에 진행중인 내 코드입니다. 이것은 당신이 당신의 프로그램에서 당신의 모든 시간을 보내는 곳을 알려줍니다.

하지만 실제로는 괜찮습니다. 코딩 문제를 제쳐두고 (filehandles에 타입 그램을 사용하고 있는데, 두 개의 인수 형식 인 open()을 사용하고 있는데, 쿼리에 자리 표시자를 사용하지 않고 있습니다.) 성능 문제로는 할 수있는 것이 훨씬 많다고 생각하지 않습니다. 그러나 그런 다음이를 결정하기 위해 적절한 프로파일 링을 수행해야합니다.

+0

입력 해 주셔서 감사합니다. – jdamae

4

테이블 이름을 실행할 매개 변수로 사용할 수 없습니다. 이것은 perldoc DBI에 설명되어 있습니다 :

With most drivers, placeholders can't be used for any element of a statement 
that would prevent the database server from validating the statement and 
creating a query execution plan for it. For example: 

    "SELECT name, age FROM ?"   # wrong (will probably fail) 
    "SELECT name, ? FROM people" # wrong (but may not 'fail') 

BTW,이 코드를 최적화하려는 경우, 당신은 DBI를 호출 mysql에 전화를 교체로 시작해야합니다

my @tbls = @{ $dbh->selectcol_arrayref('SHOW TABLES') }; 
+1

그리고 어쨌든별로 쓸모가 없을 것입니다. 쿼리 계획은 문제의 테이블에 조금 의존적입니다. –

+0

확인과 입력을 주셔서 감사합니다. 또한 WHERE 절에'?'를 사용하는 것을 볼 수 있습니다. – jdamae

0

일반적으로 fetchrow_arrayref가 빠르다 어레이를 재사용 할 때 fetchrow_array보다. 바인드 된 열과 결합하면 대개 더 빠르지 만 반환 된 데이터에 대한 참조를 저장하지 않도록 조심해야하므로 fetchrow_arrayref에 대한 DBI 문서를 읽으십시오. fetchall_arrayref는 여기에서하는 것보다 빠를 수도 있지만 선택 항목이 반환하는 행 수에 따라 크게 달라질 수 있습니다.

관련 문제