Как использовать заполнители имен таблиц в подготовленном утверждении? - PullRequest
0 голосов
/ 30 марта 2011

Мне нужна помощь Perl в настройке этого кода для оптимизации использования этого оператора DBI prepare .Я уверен, что могу оптимизировать / ускорить это больше.Я думаю, что у меня это настроено правильно, где у меня есть одно соединение, но я хочу убедиться, что я разобрал запрос один раз и просто заменил изменение параметра only (1).Я просто не уверен, как это организовать.

Я в основном беру список таблиц и зацикливаю их в качестве входных данных для одного запроса.По сути, это тот же запрос с другим именем таблицы.

Может кто-нибудь показать мне, как я могу оптимизировать это?

Вот мой код в процессе:

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: $!";
};

Ответы [ 3 ]

4 голосов
/ 30 марта 2011

Имя таблицы нельзя использовать в качестве параметра для выполнения.Это задокументировано в 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')

Кстати, если вы хотите оптимизировать этот код, вы должны начать с замены вызова на mysql вызовом для DBI:

my @tbls = @{ $dbh->selectcol_arrayref('SHOW TABLES') };
2 голосов
/ 30 марта 2011

Запустите ваш код через профилировщик, например NYTProf .Это скажет вам, где вы проводите все свое время в своей программе.

Но на самом деле, это выглядит хорошо для меня.Помимо проблем с кодированием (вы используете typeglobs для файловых дескрипторов, вы используете форму с двумя аргументами open(), вы не используете заполнители в своих запросах) Я не думаю, что вы можете сделать гораздо больше из производительностивопрос.Но тогда вам нужно выполнить правильное профилирование, чтобы определить это.

0 голосов
/ 31 марта 2011

Вообще говоря, fetchrow_arrayref быстрее, чем fetchrow_array, поскольку он повторно использует массив. В сочетании со связанными столбцами это обычно даже быстрее, но читайте документы DBI для fetchrow_arrayref, так как вы должны быть осторожны, чтобы не хранить ссылки на возвращенные данные (что вы не делаете). fetchall_arrayref также может быть быстрее, чем то, что вы здесь делаете, но это в значительной степени зависит от того, сколько строк возвращает ваш select.

...