Perl DBI, самый быстрый способ получить единственное скалярное значение - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть этот код для подсчета значений.

Короткий путь:

my $count = $dbh->selectrow_array("SELECT COUNT(name) AS RESCOUNT FROM users");

Длинный путь

my $sth = $dbh->prepare("SELECT COUNT(name) AS RESCOUNT FROM users");
$sth->execute() or die "$DBI::errstr";
my $count = $sth->fetchrow_array();
$sth->finish;

selectrow_array, fetchrow_array -> но я надеваюне нужен массив.Я проверил документы, но ничего не нашел для скаляров.Просто методы для массивов и хэшей.Метод, который я использую, достаточно быстр, но мне было просто интересно, есть ли лучший, самый быстрый способ получить единственное значение из вызова.Или это самый быстрый способ?

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Если «модерн» означает «я только недавно слышал об этом», я чувствую себя совершенно современно с bind_col и bind_columns DBI.Извлечение из сообщения героя DBI Тима Бунса ...

Для вашего случая:

my $sth = $dbh->prepare("SELECT COUNT(name) AS RESCOUNT FROM users");
my $count = 0;
$sth->bind_col(1,\$count);  # bind to a reference to the variable
$sth->execute() or die "$DBI::errstr";
$sth->fetch;
print $count;

В цикле для оператора SELECT, возвращающего несколько записей:

my $sth = $dbh->prepare(qq{SELECT name FROM users WHERE zip_code == '20500'});
my $name = '';
$sth->bind_col(1,\$name);  # bind to a reference to the variable
$sth->execute() or die "$DBI::errstr";
while ($sth->fetch) {
    print $name, "\n";
}

И с bind_columns это работает:

my $sth = $dbh->prepare(qq{SELECT name,phone,address FROM users WHERE zip_code == '20500'});
my @fields = qw/name phone address/; 
# With a 'SELECT All * ...', get all columns with @{$sth->{NAME_lc}}
my %data;
$sth->bind_columns( \( @data{@fields} ) ); # \(...) gives references to its elements
$sth->execute() or die "$DBI::errstr";
while ($sth->fetch) {
    print "$data{name} lives at $data{address}, with phone $data{phone}.", "\n";
}

После того, как установка обработана, цикл легко написать и быстро запустить.(Но, тест).

HTH, извинитесь, если это слишком сильно отличается от постановки задачи ОП.Но это самый простой и прямой способ получить ваши возвращенные данные в виде переменных, которые вы хотите, так что вы можете перейти к каким-то действиям с ними ...

0 голосов
/ 21 февраля 2019

Самый быстрый способ - использовать fetchrow_arrayref или selectrow_arrayref, в зависимости от того, сколько исполнений у вас есть.Это действительно имеет значение, только если выполняется в цикле, и у вас есть тысячи (или, скорее, сотни тысяч) строк.

При использовании fetchrow_array, он будет делать копию каждый раз, что замедляет работу.Также имейте в виду, что поведение для скалярного контекста определено только частично .

При вызове в скалярном контексте для дескриптора оператора, который имеет более одного столбца, он не определенвернет ли драйвер значение первого столбца или последнего.Так что не делайте этого.

Вы также можете сделать bind_col, который работает со ссылками.

Раньше для DBI была хорошая презентацияскорости около 10 или более лет назад, которые я не могу найти прямо сейчас.Также взгляните на эту очень старую статью Perlmonks , в которой довольно много объясняется производительность.

Имейте в виду, что оптимизацию следует выполнять только тогда, когда вы действительно в ней нуждаетесь.Большую часть времени вы не будете.

...