'val VARCHAR(255) NOT NULL)');
 }
 
-sub each_id_batch {
-       my ($self, $cb) = @_;
+sub id_batch {
+       my ($self, $num, $cb) = @_;
        my $dbh = $self->{dbh};
-       my $n = 0;
-       my $total = 0;
-       my $nr;
        my $sth = $dbh->prepare('SELECT num FROM msgmap WHERE num > ? '.
                                'ORDER BY num ASC LIMIT 1000');
-       while (1) {
-               $sth->execute($n);
-               my $ary = $sth->fetchall_arrayref;
-               @$ary = map { $_->[0] } @$ary;
-               $nr = scalar @$ary;
-               last if $nr == 0;
-               $total += $nr;
-               $n = $ary->[-1];
-               $cb->($ary);
-       }
-       $total;
+       $sth->execute($num);
+       my $ary = $sth->fetchall_arrayref;
+       @$ary = map { $_->[0] } @$ary;
+       my $nr = scalar @$ary;
+       $cb->($ary) if $nr;
+       $nr;
 }
 
 1;
 
 use Time::HiRes qw(gettimeofday tv_interval ualarm);
 use constant {
        r501 => '501 command syntax error',
+       long_response_limit => 0xffffffff,
 };
 
 my @OVERVIEW = qw(Subject From Date Message-ID References Bytes Lines);
                more($self, $res);
        }
 
-       my $ng = $self->{ng} or return '412 no newsgroup selected';
-       # Ugh this can be silly expensive for big groups
-       $ng->mm->each_id_batch(sub {
-               my ($ary) = @_;
-               more($self, join("\r\n", @$ary));
+       $self->{ng} or return '412 no newsgroup selected';
+       $self->long_response(0, long_response_limit, sub {
+               my ($i) = @_;
+               my $nr = $self->{ng}->mm->id_batch($$i, sub {
+                       my ($ary) = @_;
+                       more($self, join("\r\n", @$ary));
+               });
+
+               # -1 to adjust for implicit increment in long_response
+               $$i = $nr ? $$i + $nr - 1 : long_response_limit;
        });
-       '.'
 }
 
 sub parse_time {
 
        $ts .= '..';
        my $opts = { asc => 1, limit => 1000, offset => 0 };
-
-       my $end = 0xffffffff; # would like to read 4 billion messages?
-       $self->long_response(0, $end, sub {
+       $self->long_response(0, long_response_limit, sub {
                my ($i) = @_;
                my $srch = $srch[0];
                my $res = $srch->query($ts, $opts);
                        if (@srch) { # continue onto next newsgroup
                                $opts->{offset} = 0;
                        } else { # break out of the long response.
-                               $$i = $end;
+                               $$i = long_response_limit;
                        }
                }
        });