Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> аспекты работы DBD 
:(
    Опции темы
yorm
Дата 12.6.2008, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 1.10.2006

Репутация: нет
Всего: нет



Подскажите, пожалуйста

я делаю запрос в postgres через DBD

Код

...
$sth = $dbh->execute($blah);
while (my $row = $sth->fetchrow_arrayref()) {
    # some calculations
}


я так понимаю, что возврат уже инкапсулирован в sth?
а можно ли как-то ограничить возврат?

т.е. если возвращается, например 1000 записей, выбрать сначала 100, потом еще и еще (реальная база имеет около десятка миллиардов записей). Чтобы не хранить все в памяти?
или такое невозможно и придется пользовать лимит в запросе?

и можно ли как-то оптимизировать выборку возврата, чтобы работала побыстрее и занимала поменьше памяти? (т.е не через SQL оптимизировать, а именно алгоритм выборки)

Это сообщение отредактировал(а) yorm - 12.6.2008, 16:52
PM MAIL   Вверх
tolkien
Дата 12.6.2008, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 277
Регистрация: 5.4.2008

Репутация: 4
Всего: 4



Использовать другой метод. Например bind_columns

my $sth = $dbh->prepare($sql);
$sth->execute or die $dbh->errstr;
my ($field1, $field2, $field3) = (undef, undef, undef); 
$sth->bind_columns(undef, \($filed1, $field2, field3));
   
while($sth->fetch())
{
    print "$filed1 $field2 $field3\n";
}
PM MAIL   Вверх
gcc
Дата 14.6.2008, 04:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: 1
Всего: 17



Цитата(yorm @ 12.6.2008,  16:41)
Подскажите, пожалуйста

я делаю запрос в postgres через DBD

Код

...
$sth = $dbh->execute($blah);
while (my $row = $sth->fetchrow_arrayref()) {
    # some calculations
}


я так понимаю, что возврат уже инкапсулирован в sth?
а можно ли как-то ограничить возврат?

т.е. если возвращается, например 1000 записей, выбрать сначала 100, потом еще и еще (реальная база имеет около десятка миллиардов записей). Чтобы не хранить все в памяти?
или такое невозможно и придется пользовать лимит в запросе?

и можно ли как-то оптимизировать выборку возврата, чтобы работала побыстрее и занимала поменьше памяти? (т.е не через SQL оптимизировать, а именно алгоритм выборки)

Код

limit 


вот пример

Код

$sthh = $dbh->prepare("
        SELECT count(*) FROM com where nam= ?
        ");
$sthh->execute($iddd);
#$sthh->finish();
#$from=1;
($rv)=$sthh->fetchrow_array();
$total_articles_number = $rv;
#$total_articles_number = 79;   #����� ���������� ������
$articles_per_page=10; # ���������� ������ �� ��������
#�������� ���������� �������
#$total_pages = ceil($total_articles_number/$articles_per_page);
$total_pages = floor($total_articles_number/$articles_per_page);
if ($from > $total_pages ) {
$from=$total_pages-1;
}
$jj=0;
#$ii=0;
if ($from eq "") {
$jj=0;
#$ii=0;
#$jj=0;
#$ii=10;
}
else {
$jj=0;
#$ii=0;
$jj=$from*$articles_per_page;
#$ii=($from*$articles_per_page)+10;
}
#print "$jj _ $ii _ $from";
#$sthh->finish();
#$from=1;
$sth = $dbh->prepare("
        select 
id,
nam,
tex,
regr
        from com
        where
        nameid = ?
                LIMIT ?, 10
");
$sth->execute($iddd,$jj);
$dbh->disconnect();
#$sth->finish();
#  $rv = $sth->rows;
#$from=1;
$page_number=-1;
# ��������� ���� - ���������� �������� ����� ���������� �������
print << "[INFO]";
</TABLE>
bla-bla 
<TR>
        <TD background="images/tjpg" WIDTH=263 HEIGHT=100% ALT="" valign="top">
<center>
[INFO]
for ($i=-1; $i<$total_pages; $i++) {
# �������� �������� $from (��� $page_number) ��� ������������� � ������������ ������
#$page_number=$i*$articles_per_page;п╒п╣п╨я│я┌ п║п╬п╬п╠я┴п╣п╫п╦я▐:
# ���� $page_number (���������� ��� �������� ���� �������� �� $from �������) �� ������������� ������� ��������,
# ������� ������ �� �������� �� ��������� $from ������ $page_number
$page_number++;
last if ($total_pages < 1);
next if ($page_number > $from+3);
next if ($page_number < $from-3);
if ($page_number!=$from) {
#$page_number++;
print << "[INFO3]";
 <a href="http://.org/sites/index2.pl?idd=$iddd&from=$page_number"> | $page_number |</a> 
[INFO3]
}
# ����� ������ ������� ����� �������� - ������ ������ �������������,
# ��������� �� �� ������ �������� ���� �� ������� ��������
else {print $i+1;} # ���� page_number - ������� �������� - ������ �� ������� (������ �� ������)
}

PM WWW ICQ Skype GTalk Jabber   Вверх
ginnie
Дата 16.6.2008, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Уважаемый gcc, вариант с LIMIT будет тормозить при больших значениях смещения. Лучше использовать конкретные значения id (проиндексированное уникальное возрастающее числовое значение), если такое поле есть в таблице (SELECT ... WHERE id > NNNN LIMIT 10).


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
sir_nuf_nuf
Дата 18.6.2008, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



А они и не будут хранится все в памяти.
Данные не должны извлекаться из базы в момент $dbh->execute($blah).
СУБД будет выдавать тебе данные по мере необходимости, т.е. 
при каждом вызове $sth->fetchrow_arrayref() ты будешь получать кусочек от результата твоего запроса.

P.S. на самом деле данные передаются не по строке, а большими кусками, но никак не все сразу.

Достаточно открыть какой - нть sql_plus или psql и сделать select * from biiiiig_taaable;
Результат ты получишь быстро, очевидно, что не всю таблицу в память клиентского приложения перекачали.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
gcc
Дата 25.4.2009, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: 1
Всего: 17



Цитата(ginnie @ 16.6.2008,  11:55)
Уважаемый gcc, вариант с LIMIT будет тормозить при больших значениях смещения. Лучше использовать конкретные значения id (проиндексированное уникальное возрастающее числовое значение), если такое поле есть в таблице (SELECT ... WHERE id > NNNN LIMIT 10).

есть модуль http://kobesearch.cpan.org/htdocs/DBIx-Abs....pm.html#clone-

а как написать запрос без LIMIT, как с эмулировать его?

что такое "уникальное возрастающее числовое значение"? если id, но если какая-го данная строка в диапазоне лимита будет удалена как тогда лимит сделать?



Это сообщение отредактировал(а) gcc - 25.4.2009, 18:39
PM WWW ICQ Skype GTalk Jabber   Вверх
ginnie
Дата 27.4.2009, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Цитата(gcc @  25.4.2009,  18:37 Найти цитируемый пост)
а как написать запрос без LIMIT, как с эмулировать его?


Почему возникла необходимость писать запрос без LIMIT? Я не говорил, что его нужно избегать, я лишь написал, что следует избегать использования больших смещений в LIMIT, заменяя их (по возможности) на использование условий с id. Например, запрос 

Код

SELECT url FROM links ORDER BY id LIMIT 100000, 20


лучше заменить на 

Код

SELECT url FROM links WHERE id > 100000 ORDER BY id LIMIT 20




--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
gcc
Дата 27.4.2009, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: 1
Всего: 17



тогда я не так понял.....

вот в этом модуле нету LIMIT http://kobesearch.cpan.org/htdocs/DBIx-Abs....pm.html#clone-

как его сделать LIMIT? 

(или там надо переделать модуль сам?)
PM WWW ICQ Skype GTalk Jabber   Вверх
ginnie
Дата 27.4.2009, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



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

Это сообщение отредактировал(а) ginnie - 27.4.2009, 17:32


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
sir_nuf_nuf
Дата 27.4.2009, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



gcc, пожалуй что надо.
Фишка в чем - с точки зрения ORM - выборка - это множество объектов
Из принципов СУБД - выборка неупорядочена (если нет явного указания) и в принципе порядок объектов может
отличаться при повторных запросах.

Тогда с какого бока ORM должна сама ограничивать множество выбираемых объектов. Это не ее дело.

Вставляйте SQL код 


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1111 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.