[PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Joost Kraaijeveld
Hi,

I must convert an old table into a new table. The conversion goes at ~
100 records per second. Given the fact that I must convert 40 million
records, it takes too much time: more hours than the 48 hour weekend I
have for the conversion;-).

The tables are rather simple: both tables only have a primary key
constraint (of type text) and no other indexes. I only copy 3 columns. I
use Java for the conversion. For the exact code see below.

During the conversion my processor load is almost non existant. The
harddisk throughput is ~ 6 megabyte/second max (measured with iostat).

My platform is Debian Sarge AMD64. My hardware is a Tyan Thunder K8W
2885 motherboard, 2 Opteron 248 processors, 2 GB RAM, a SATA bootdisk
with / and swap, and a 3Ware 9500S-8 RAID-5 controller with 5 attached
SATA disks with /home and /var. /var contains *all* PostgreSQL log and
database files (default Debian installation).

Output of hdparm -Tt /dev/sdb (sdb is the RAID opartition)

/dev/sdb:
 Timing cached reads:   1696 MB in  2.00 seconds = 846.86 MB/sec
 Timing buffered disk reads:  246 MB in  3.01 seconds =  81.79 MB/sec


I want to determine the cause of my performance problem (if it is one).

1. Is this a performance I can expect?
2. If not, how can I determine the cause?
3. Can I anyhow improve the performance without replacing my hardware,
e.g. by tweaking the software?
4. Is there a Linux (Debian) tool that I can use to benchmark write
performance?



-- 
Groeten,

Joost Kraaijeveld
Askesis B.V.
Molukkenstraat 14
6524NB Nijmegen
tel: 024-3888063 / 06-51855277
fax: 024-3608416
e-mail: [EMAIL PROTECTED]
web: www.askesis.nl 


The Java code I use for the conversion  :

 
ResultSet resultSet = selectStatement.executeQuery(
select ordernummer, orderdatum, klantnummer from odbc.orders order by
ordernummer);

connection.setAutoCommit(false);

PreparedStatement ordersInsertStatement = 
connection.prepareStatement(insert into prototype.orders
(objectid,ordernumber,orderdate,customernumber) values (?,?,?,?)); 


while( resultSet.next() )
{

if( (++record % 100) == 0){
System.err.println( handling record:  + record);
}

// the next line can do  1.000.000 objectId/sec
String orderObjectId = ObjectIdGenerator.newObjectId();
ordersInsertStatement.setString(1,orderObjectId);
ordersInsertStatement.setInt(2,resultSet.getInt(ordernummer)); 
ordersInsertStatement.setDate(3,resultSet.getDate(orderdatum)); 
ordersInsertStatement.setInt(4,resultSet.getInt(klantnummer)); 

ordersInsertStatement.execute();

}   

connection.commit();


---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faq


Re: [PERFORM] SELECT LIMIT 1 VIEW Performance Issue

2005-09-23 Thread K C Lau
Thank you all for your suggestions. I' tried, with some variations too, but 
still no success. The times given are the best of a few repeated tries on 
an 8.1 beta 2 db freshly migrated from 8.0.3 on Windows.


For reference, only the following gets the record quickly:

esdt= explain analyze select PlayerID,AtDate from Player a
 where PlayerID='0' and AtDate = (select b.AtDate from Player b
 where b.PlayerID = '0' order by b.PlayerID desc, b.AtDate desc LIMIT 1);

 Index Scan using pk_player on player a  (cost=0.75..4.26 rows=1 width=23) 
(actual time=0.054..0.057 rows=1 loops=1)
   Index Cond: (((playerid)::text = '0'::text) AND ((atdate)::text = 
($0)::text))

   InitPlan
 -  Limit  (cost=0.00..0.75 rows=1 width=23) (actual 
time=0.027..0.028 rows=1 loops=1)
   -  Index Scan Backward using pk_player on player 
b  (cost=0.00..1323.05 rows=1756 width=23) (actual time=0.023..0.023 rows=1 
loops=1)

 Index Cond: ((playerid)::text = '0'::text)
 Total runtime: 0.132 ms

At 02:19 05/09/23, Kevin Grittner wrote:

Have you tried the best choice pattern -- where you select the set of
candidate rows and then exclude those for which a better choice
exists within the set?  I often get better results with this pattern than
with the alternatives.


esdt= explain analyze select PlayerID,AtDate from Player a where 
PlayerID='0'
and not exists (select * from Player b where b.PlayerID = a.PlayerID and 
b.AtDate  a.AtDate);


 Index Scan using pk_player on player a  (cost=0.00..3032.46 rows=878 
width=23)

(actual time=35.820..35.823 rows=1 loops=1)
   Index Cond: ((playerid)::text = '0'::text)
   Filter: (NOT (subplan))
   SubPlan
 -  Index Scan using pk_player on player b  (cost=0.00..378.68 
rows=389 width=776) (actual time=0.013..0.013 rows=1 loops=1743)
   Index Cond: (((playerid)::text = ($0)::text) AND 
((atdate)::text  ($1)::text))

 Total runtime: 35.950 ms

Note that it is faster than the LIMIT 1:

esdt= explain analyze select PlayerID,AtDate from Player a where 
PlayerID='0' and AtDate = (select b.AtDate from Pl
ayer b where b.PlayerID = a.PlayerID order by b.PlayerID desc, b.AtDate 
desc LIMIT 1);


 Index Scan using pk_player on player a  (cost=0.00..2789.07 rows=9 
width=23) (actual time=41.366..41.371 rows=1 loops=1)

   Index Cond: ((playerid)::text = '0'::text)
   Filter: ((atdate)::text = ((subplan))::text)
   SubPlan
 -  Limit  (cost=0.00..0.83 rows=1 width=23) (actual 
time=0.013..0.014 rows=1 loops=1743)
   -  Index Scan Backward using pk_player on player 
b  (cost=0.00..970.53 rows=1166 width=23) (actual time=0.008..0.008 rows=1 
loops=1743)

 Index Cond: ((playerid)::text = ($0)::text)
 Total runtime: 41.490 ms

At 02:07 05/09/23, Merlin Moncure wrote:

 Here is a trick I use sometimes with views, etc.  This may or may not be
 effective to solve your problem but it's worth a shot.  Create one small
 SQL function taking date, etc. and returning the values and define it
 immutable.  Now in-query it is treated like a constant.


esdt= create or replace function player_max_atdate (varchar(32)) returns 
varchar(32) as $$
esdt$  select atdate from player where playerid = $1 order by playerid 
desc, AtDate desc limit 1;

esdt$ $$ language sql immutable;
CREATE FUNCTION
esdt= create or replace view VCurPlayer3 as select * from Player where 
AtDate = player_max_atdate(PlayerID);

CREATE VIEW
esdt= explain analyze select PlayerID,AtDate from VCurPlayer3 where 
PlayerID='0';


 Index Scan using pk_player on player  (cost=0.00..1331.83 rows=9 
width=23) (actual time=65.434..65.439 rows=1 loops=1)

   Index Cond: ((playerid)::text = '0'::text)
   Filter: ((atdate)::text = (player_max_atdate(playerid))::text)
 Total runtime: 65.508 ms

While it says loops=1, the time suggests that it is going through all 1743 
records for that PlayerID.


I tried to simulate the fast subquery inside the function, but it is taking 
almost twice as much time:


esdt= create or replace function player_max_atdate (varchar(32)) returns 
varchar(32) as $$
esdt$  select atdate from player a where playerid = $1 and AtDate = 
(select b.AtDate from Player b

esdt$  where b.PlayerID = $1 order by b.PlayerID desc, b.AtDate desc LIMIT 1);
esdt$ $$ language sql immutable;
CREATE FUNCTION
esdt= explain analyze select PlayerID,AtDate from VCurPlayer3 where 
PlayerID='0';


 Index Scan using pk_player on player  (cost=0.00..1331.83 rows=9 
width=23) (actual time=119.369..119.373 rows=1 loops=1)

   Index Cond: ((playerid)::text = '0'::text)
   Filter: ((atdate)::text = (player_max_atdate(playerid))::text)
 Total runtime: 119.441 ms

Adding another LIMIT 1 inside the function makes it even slower:

esdt= create or replace function player_max_atdate (varchar(32)) returns 
varchar(32) as $$
esdt$  select atdate from player where playerid = $1 and AtDate = (select 
b.AtDate from Player b

esdt$  where b.PlayerID = $1 order by b.PlayerID 

Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Ulrich Wisser

Hi Joost,

why do you convert programmatically? I would do something like

create sequence s_objectid;

insert into 
prototype.orders(objectid,ordernumber,orderdate,customernumber)

select next_val('s_objectid'),ordernummer, orderdatum, klantnummer from
odbc.orders


Sounds a lot faster to me.


/Ulrich

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
  choose an index scan if your joining column's datatypes do not
  match


[PERFORM] Releasing memory during External sorting?

2005-09-23 Thread Simon Riggs
I have concerns about whether we are overallocating memory for use in
external sorts. (All code relating to this is in tuplesort.c)

When we begin a sort we allocate (work_mem | maintenance_work_mem) and
attempt to do the sort in memory. If the sort set is too big to fit in
memory we then write to disk and begin an external sort. The same memory
allocation is used for both types of sort, AFAICS.

The external sort algorithm benefits from some memory but not much.
Knuth says that the amount of memory required is very low, with a value
typically less than 1 kB. I/O overheads mean that there is benefit from
having longer sequential writes, so the optimum is much larger than
that. I've not seen any data that indicates that a setting higher than
16 MB adds any value at all to a large external sort. I have some
indications from private tests that very high memory settings may
actually hinder performance of the sorts, though I cannot explain that
and wonder whether it is the performance tests themselves that have
issues.

Does anyone have any clear data that shows the value of large settings
of work_mem when the data to be sorted is much larger than memory? (I am
well aware of the value of setting work_mem higher for smaller sorts, so
any performance data needs to reflect only very large sorts). 

If not, I would propose that when we move from qsort to tapesort mode we
free the larger work_mem setting (if one exists) and allocate only a
lower, though still optimal setting for the tapesort. That way the
memory can be freed for use by other users or the OS while the tapesort
proceeds (which is usually quite a while...).

Feedback, please.

Best Regards, Simon Riggs


---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Michael Stone

On Fri, Sep 23, 2005 at 08:49:27AM +0200, Joost Kraaijeveld wrote:

3. Can I anyhow improve the performance without replacing my hardware,
e.g. by tweaking the software?


It's not clear what your object id generator does. If it's just a
sequence, it's not clear that you need this program at all--just use a
SELECT INTO and make the object id a SERIAL.

If you do need to control the object id or do some other processing
before putting the data into the new table, rewrite to use a COPY
instead of an INSERT.

Mike Stone

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
  subscribe-nomail command to [EMAIL PROTECTED] so that your
  message can get through to the mailing list cleanly


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Joost Kraaijeveld
On Fri, 2005-09-23 at 05:55 -0400, Michael Stone wrote:
 It's not clear what your object id generator does. If it's just a
 sequence, it's not clear that you need this program at all--just use a
 SELECT INTO and make the object id a SERIAL.
It generates a GUID (and no, I do not want to turn this in a discussion
about GUIDs). As in the Java code comment: it is not the generation of
the GUID that is the problem (that is, I can generate millions of them
per second.)

 If you do need to control the object id or do some other processing
 before putting the data into the new table, rewrite to use a COPY
 instead of an INSERT.
It is actually the shortest piece of code that gives me a poor
performance. The conversion problem is much, much larger and much much
more complicated. 

I suspect that either my hardware is to slow (but then again, see the
specs), or my Debian is to slow, or my PostgreSQL settings are wrong.

But I have no clue where to begin with determining the bottleneck (it
even may be a normal performance for all I know: I have no experience
with converting such (large) database).

Any suggestions?


-- 
Groeten,

Joost Kraaijeveld
Askesis B.V.
Molukkenstraat 14
6524NB Nijmegen
tel: 024-3888063 / 06-51855277
fax: 024-3608416
e-mail: [EMAIL PROTECTED]
web: www.askesis.nl 



---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faq


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Michael Stone

On Fri, Sep 23, 2005 at 12:21:15PM +0200, Joost Kraaijeveld wrote:

On Fri, 2005-09-23 at 05:55 -0400, Michael Stone wrote:

It's not clear what your object id generator does. If it's just a
sequence, it's not clear that you need this program at all--just use a
SELECT INTO and make the object id a SERIAL.

It generates a GUID (and no, I do not want to turn this in a discussion
about GUIDs). As in the Java code comment: it is not the generation of
the GUID that is the problem (that is, I can generate millions of them
per second.)


I didn't say it was, did I? If you use a SELECT INTO instead of
SELECTing each record and then reINSERTing it you avoid a round trip
latency for each row. There's a reason I said if it's just a sequence.


If you do need to control the object id or do some other processing
before putting the data into the new table, rewrite to use a COPY
instead of an INSERT.

It is actually the shortest piece of code that gives me a poor
performance. The conversion problem is much, much larger and much much
more complicated. 


Ok, that's great, but you didn't respond to the suggestion of using COPY
INTO instead of INSERT.


But I have no clue where to begin with determining the bottleneck (it
even may be a normal performance for all I know: I have no experience
with converting such (large) database).

Any suggestions?


Respond to the first suggestion?

Mike Stone

---(end of broadcast)---
TIP 4: Have you searched our list archives?

  http://archives.postgresql.org


Re: [PERFORM] SELECT LIMIT 1 VIEW Performance Issue

2005-09-23 Thread Simon Riggs
On Thu, 2005-09-22 at 18:40 +0800, K C Lau wrote: 
   esdt= explain analyze select PlayerID,AtDate from Player a
 where PlayerID='0' and AtDate = (select b.AtDate from Player b
 where b.PlayerID = a.PlayerID order by b.PlayerID desc, b.AtDate desc
   LIMIT 1);

I think you should try:

select distinct on (PlayerID) PlayerID,AtDate from Player a
where PlayerID='0' order by PlayerId, AtDate Desc;

Does that work for you?

Best Regards, Simon Riggs


---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Arjen van der Meijden

On 23-9-2005 13:05, Michael Stone wrote:

On Fri, Sep 23, 2005 at 12:21:15PM +0200, Joost Kraaijeveld wrote:

Ok, that's great, but you didn't respond to the suggestion of using COPY
INTO instead of INSERT.


But I have no clue where to begin with determining the bottleneck (it
even may be a normal performance for all I know: I have no experience
with converting such (large) database).

Any suggestions?



Respond to the first suggestion?


Another suggestion:
How many indexes and constraints are on the new table?
Drop all of them and recreate them once the table is filled. Of course 
that only works if you know your data will be ok (which is normal for 
imports of already conforming data like database dumps of existing tables).
This will give major performance improvements, if you have indexes and 
such on the new table.


Best regards,

Arjen

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
  subscribe-nomail command to [EMAIL PROTECTED] so that your
  message can get through to the mailing list cleanly


Re: [PERFORM] tsearch2 seem very slow

2005-09-23 Thread Oleg Bartunov

On Fri, 23 Sep 2005, Ahmad Fajar wrote:


Hi Oleg,

I didn't deny on the third repeat or more, it can reach  600 msec. It is
only because the result still in postgres cache, but how about in the first
run? I didn't dare, the values is un-acceptable. Because my table will grows
rapidly, it's about 10 rows per-week. And the visitor will search
anything that I don't know, whether it's the repeated search or new search,
or whether it's in postgres cache or not.


if you have enoush shared memory postgresql will keep index pages there.




I just compare with http://www.postgresql.org, the search is quite fast, and
I don't know whether the site uses tsearch2 or something else. But as fas as
I know, if the rows reach 100 milion (I have try for 200 milion rows and it
seem very slow), even if don't use tsearch2, only use simple query like:
select f1, f2 from table1 where f2='blabla',
and f2 is indexes, my postgres still slow on the first time, about 10 sec.
because of this I tried something brand new to fullfill my needs. I have
used fti, and tsearch2 but still slow.

I don't know what's going wrong with my postgres, what configuration must I
do to perform the query get fast result. Or must I use enterprisedb 2005 or
pervasive postgres (both uses postgres), I don't know very much about these
two products.


you didn't show us your configuration (hardware,postgresql and tsearch2),
explain analyze of your queries, so we can't help you.
How big is your database, tsearch2 index size ?




Regards,
ahmad fajar


-Original Message-
From: Oleg Bartunov [mailto:[EMAIL PROTECTED]
Sent: Jumat, 23 September 2005 14:36
To: Ahmad Fajar
Cc: pgsql-performance@postgresql.org
Subject: Re: [PERFORM] tsearch2 seem very slow

Ahmad,

how fast is repeated runs ? First time system could be very slow.
Also, have you checked my page
http://www.sai.msu.su/~megera/oddmuse/index.cgi/Tsearch_V2_Notes
and some info about tsearch2 internals
http://www.sai.msu.su/~megera/oddmuse/index.cgi/Tsearch_V2_internals

Oleg
On Thu, 22 Sep 2005, Ahmad Fajar wrote:


I have about 419804 rows in my article table. I have installed tsearch2

and

its gist index correctly.

My table structure is:

CREATE TABLE tbarticles

(

 articleid int4 NOT NULL,

 title varchar(250),

 mediaid int4,

 datee date,

 content text,

 contentvar text,

 mmcol float4 NOT NULL,

 sirkulasi float4,

 page varchar(10),

 tglisidata date,

 namapc varchar(12),

 usere varchar(12),

 file_pdf varchar(255),

 file_pdf2 varchar(50),

 kolom int4,

 size_jpeg int4,

 journalist varchar(120),

 ratebw float4,

 ratefc float4,

 fti tsvector,

 CONSTRAINT pk_tbarticles PRIMARY KEY (articleid)

) WITHOUT OIDS;

Create index fti_idx1 on tbarticles using gist (fti);

Create index fti_idx2 on tbarticles using gist (datee, fti);



But when I search something like:

Select articleid, title, datee from tbarticles where fti @@
to_tsquery('susilobambangyudhoyonojusufkalla');

It takes about 30 sec. I run explain analyze and the index is used
correctly.



Then I try multi column index to filter by date, and my query something
like:

Select articleid, title, datee from tbarticles where fti @@
to_tsquery('susilobambangyudhoyonojusufkalla') and datee =

'2002-01-01'

and datee = current_date

An it still run about 25 sec. I do run explain analyze and my multicolumn
index is used correctly.

This is not acceptable if want to publish my website if the search took

very

longer.



I have run vacuum full analyze before doing such query. What going wrong
with my query?? Is there any way to make this faster?

I have try to tune my postgres configuration, but it seem helpless. My

linux

box is Redhat 4 AS, and

the hardware: 2 GB RAM DDR 400, 2x200 GB Serial ATA 7200RPM and configure

as

RAID0 (just for postgres data), my sistem run at EIDE 80GB 7200 RPM.



Please.help.help.




Regards,
Oleg
_
Oleg Bartunov, sci.researcher, hostmaster of AstroNet,
Sternberg Astronomical Institute, Moscow University (Russia)
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(095)939-16-83, +007(095)939-23-83



Regards,
Oleg
_
Oleg Bartunov, sci.researcher, hostmaster of AstroNet,
Sternberg Astronomical Institute, Moscow University (Russia)
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(095)939-16-83, +007(095)939-23-83

---(end of broadcast)---
TIP 4: Have you searched our list archives?

  http://archives.postgresql.org


Re: [PERFORM] SELECT LIMIT 1 VIEW Performance Issue

2005-09-23 Thread K C Lau

At 19:15 05/09/23, Simon Riggs wrote:

select distinct on (PlayerID) PlayerID,AtDate from Player a
where PlayerID='0' order by PlayerId, AtDate Desc;

Does that work for you?

Best Regards, Simon Riggs


esdt= explain analyze select distinct on (PlayerID) PlayerID,AtDate from 
Player a where PlayerID='0' order by PlayerId, AtDate Desc;
 Unique  (cost=1417.69..1426.47 rows=2 width=23) (actual 
time=31.231..36.609 rows=1 loops=1)
   -  Sort  (cost=1417.69..1422.08 rows=1756 width=23) (actual 
time=31.129..32.473 rows=1743 loops=1)

 Sort Key: playerid, atdate
 -  Index Scan using pk_player on player a  (cost=0.00..1323.05 
rows=1756 width=23) (actual time=0.035..6.575 rows=1743 loops=1)

   Index Cond: ((playerid)::text = '0'::text)
 Total runtime: 36.943 ms

The sort was eliminated with: order by PlayerId Desc, AtDate Desc:

esdt= explain analyze select distinct on (PlayerID) PlayerID,AtDate from 
Player a where PlayerID='0' order by PlayerId Desc, AtDate Desc;
 Unique  (cost=0.00..1327.44 rows=2 width=23) (actual time=0.027..8.438 
rows=1 loops=1)
   -  Index Scan Backward using pk_player on player 
a  (cost=0.00..1323.05 rows=1756 width=23) (actual time=0.022..4.950 
rows=1743 loops=1)

 Index Cond: ((playerid)::text = '0'::text)
 Total runtime: 8.499 ms

That is the fastest of all queries looping the 1743 rows.
I do get the desired result by adding LIMIT 1:

esdt= explain analyze select distinct on (PlayerID) PlayerID,AtDate from 
Player a where PlayerID='0' order by PlayerId Desc, AtDate Desc LIMIT 1;


 Limit  (cost=0.00..663.72 rows=1 width=23) (actual time=0.032..0.033 
rows=1 loops=1)
   -  Unique  (cost=0.00..1327.44 rows=2 width=23) (actual 
time=0.028..0.028 rows=1 loops=1)
 -  Index Scan Backward using pk_player on player 
a  (cost=0.00..1323.05 rows=1756 width=23) (actual time=0.022..0.022 rows=1 
loops=1)

   Index Cond: ((playerid)::text = '0'::text)
 Total runtime: 0.094 ms

However, when I use that within a function in a view, it is slow again:

esdt= create or replace function player_max_atdate (varchar(32)) returns 
varchar(32) as $$
esdt$  select distinct on (PlayerID) AtDate from player where PlayerID= $1 
order by PlayerID desc, AtDate desc limit 1;

esdt$ $$ language sql immutable;
CREATE FUNCTION
esdt= create or replace view VCurPlayer3 as select * from Player where 
AtDate = player_max_atdate(PlayerID);

CREATE VIEW
esdt= explain analyze select PlayerID,AtDate from VCurPlayer3 where 
PlayerID='0';


 Index Scan using pk_player on player  (cost=0.00..1331.83 rows=9 
width=23) (actual time=76.660..76.664 rows=1 loops=1)

   Index Cond: ((playerid)::text = '0'::text)
   Filter: ((atdate)::text = (player_max_atdate(playerid))::text)
 Total runtime: 76.716 ms

Why wouldn't the function get the row as quickly as the direct sql does?

Best regards, KC.



---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

  http://www.postgresql.org/docs/faq


Re: [PERFORM] SELECT LIMIT 1 VIEW Performance Issue

2005-09-23 Thread Merlin Moncure
 At 02:07 05/09/23, Merlin Moncure wrote:
   Here is a trick I use sometimes with views, etc.  This may or may
not
 be
   effective to solve your problem but it's worth a shot.  Create
one
 small
   SQL function taking date, etc. and returning the values and
define it
   immutable.  Now in-query it is treated like a constant.
 
 esdt= create or replace function player_max_atdate (varchar(32))
returns
 varchar(32) as $$
 esdt$  select atdate from player where playerid = $1 order by
playerid
 desc, AtDate desc limit 1;
 esdt$ $$ language sql immutable;

Can you time just the execution of this function and compare vs. pure
SQL version?  If the times are different, can you do a exaplain analyze
of a prepared version of above?

prepare test(character varying) as select atdate from player where
playerid = $1 order by playerid desc, AtDate desc limit 1;

explain analyze execute test('0');

 CREATE FUNCTION
 esdt= create or replace view VCurPlayer3 as select * from Player
where
 AtDate = player_max_atdate(PlayerID);
 CREATE VIEW

This is wrong, it should have been 
create or replace view VCurPlayer3 as select *,
player_max_atdate(PlayerID) as max_date  from Player;

I did a test on a table with 124k records and a two part key, ID  date.
esp# select count(*) from parts_order_file;
count

 124158
(1 row)


esp=# select count(*) from parts_order_file where pr_dealer_no =
'000500';
 count
---
 27971
(1 row)

created same function, view v, etc.
esp=# explain analyze select * from v where pr_dealer_no = '000500'
limit 1;
 
QUERY PLAN




 Limit  (cost=0.00..3.87 rows=1 width=10) (actual time=1.295..1.297
rows=1 loops=1)
   -  Index Scan using parts_order_file_pr_dealer_no_key on
parts_order_file  (cost=0.00..109369.15
 rows=28226 width=10) (actual time=1.287..1.287 rows=1 loops=1)
 Index Cond: (pr_dealer_no = '000500'::bpchar)
 Total runtime: 1.413 ms
(4 rows)

Something is not jiving here.  However, if the server plan still does
not come out correct, try the following (p.s. why is function returning
varchar(32) and not date?):

create or replace function player_max_atdate (varchar(32)) returns date
as
$$
DECLARE
   player_record record;
   return date date;
BEGIN
   for player_record in execute
   'select atdate from player where playerid = \'' || $1 || '\'
order by playerid desc, AtDate desc limit 1;' loop
   return_date = player_record.atdate;
   end loop;
   
   return return_date;
END;
$ language plpgsql immutable;

Merlin

---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Joost Kraaijeveld
On Fri, 2005-09-23 at 13:19 +0200, Arjen van der Meijden wrote:
 Another suggestion:
 How many indexes and constraints are on the new table?
As mentioned in the first mail: in this tables only primary key
constraints, no other indexes or constraints.

 Drop all of them and recreate them once the table is filled. Of course 
 that only works if you know your data will be ok (which is normal for 
 imports of already conforming data like database dumps of existing tables).
 This will give major performance improvements, if you have indexes and 
 such on the new table.
I will test this a for perfomance improvement, but still, I wonder if ~
100 inserts/second is a reasonable performance for my software/hardware
combination.

-- 
Groeten,

Joost Kraaijeveld
Askesis B.V.
Molukkenstraat 14
6524NB Nijmegen
tel: 024-3888063 / 06-51855277
fax: 024-3608416
e-mail: [EMAIL PROTECTED]
web: www.askesis.nl 



---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly


Re: [PERFORM] optimization downgrade perfomance?

2005-09-23 Thread Tom Lane
eVl [EMAIL PROTECTED] writes:
   When executing this SELECT (see SELECT.A above) it executes in about 
 700 ms, but when I want wipe out all info about local traffic, with query 
 like this:
   SELECT * FROM ( SELECT.A ) a WHERE type = 'global';
 It executes about 1 ms - more then 10 TIMES SLOWER!

  Why this could be?

You tell us --- let's see EXPLAIN ANALYZE results for both cases.

regards, tom lane

---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Joost Kraaijeveld
On Fri, 2005-09-23 at 07:05 -0400, Michael Stone wrote: 
 On Fri, Sep 23, 2005 at 12:21:15PM +0200, Joost Kraaijeveld wrote:
 On Fri, 2005-09-23 at 05:55 -0400, Michael Stone wrote:
 I didn't say it was, did I? 
No, you did not. But only last week someon'es head was (luckely for him
only virtually) almost chopped off for suggesting the usage of GUIDs ;-)


 Ok, that's great, but you didn't respond to the suggestion of using COPY
 INTO instead of INSERT.
Part of the code I left out are some data conversions (e.g. from
path-to-file to blob, from text to date (not castable because of the
homebrew original format)). I don't believe that I can do these in a SQL
statement, can I (my knowledge of SQL as a langage is not that good)? .
However I will investigate if I can do the conversion in two steps and
check if it is faster.

But still, I wonder if ~100 inserts/second is a reasonable performance
for my software/hardware combination.


-- 
Groeten,

Joost Kraaijeveld
Askesis B.V.
Molukkenstraat 14
6524NB Nijmegen
tel: 024-3888063 / 06-51855277
fax: 024-3608416
e-mail: [EMAIL PROTECTED]
web: www.askesis.nl 



---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Arjen van der Meijden

On 23-9-2005 15:35, Joost Kraaijeveld wrote:

On Fri, 2005-09-23 at 13:19 +0200, Arjen van der Meijden wrote:
Drop all of them and recreate them once the table is filled. Of course 
that only works if you know your data will be ok (which is normal for 
imports of already conforming data like database dumps of existing tables).
This will give major performance improvements, if you have indexes and 
such on the new table.


I will test this a for perfomance improvement, but still, I wonder if ~
100 inserts/second is a reasonable performance for my software/hardware
combination.


For the hardware: no, I don't think it is for such a simple table/small 
recordsize.
I did a few batch-inserts with indexes on tables and was very 
disappointed about the time it took. But with no indexes and constraints 
left it flew and the table of 7 million records (of 3 ints and 2 
bigints) was imported in 75 seconds, on a bit simpler hardware. That was 
done using a simple pg_dump-built sql-file which was then fed to psql as 
input. And of course that used the local unix socket, not the local 
network interface (I don't know which jdbc takes).
But generating a single transaction (as you do) with inserts shouldn't 
be that much slower.


So I don't think its your hardware, nor your postgresql, although a bit 
extra maintenance_work_mem may help, if you haven't touched that.
Leaving the queries, the application and the driver. But I don't have 
that much experience with jdbc and postgresql-performance. In php I 
wouldn't select all the 40M records at once, the resultset would be in 
the clients-memory and that may actually cause trouble. But I don't know 
how that is implemented in JDBC, it may of course be using cursors and 
it would be less of a problem than perhaps.
You could try writing the inserts to file and see how long that takes, 
to eliminate the possibility of your application being slow on other 
parts than the inserting of data. If that is fast enough, a last resort 
may be to write a csv-file from java and use that with a copy-statement 
in psql ;)


Best regards,

Arjen

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PERFORM] VACUUM FULL vs CLUSTER

2005-09-23 Thread Bruno Wolff III
On Tue, Sep 20, 2005 at 14:53:19 -0400,
  Markus Benne [EMAIL PROTECTED] wrote:
 I have a table that is purged by 25% each night.  I'd like to do a
 vacuum nightly after the purge to reclaim the space, but I think I'll
 still need to do a vacuum full weekly.
 
 Would there be any benefit to doing a cluster instead of the vacuum?

If you have a proper FSM setting you shouldn't need to do vacuum fulls
(unless you have an older version of postgres where index bloat might
be an issue).

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Tom Lane
Joost Kraaijeveld [EMAIL PROTECTED] writes:
 I will test this a for perfomance improvement, but still, I wonder if ~
 100 inserts/second is a reasonable performance for my software/hardware
 combination.

Is the client code running on the same machine as the database server?
If not, what's the network delay and latency between them?

The major problem you're going to have here is at least one network
round trip per row inserted --- possibly more, if the jdbc driver is
doing helpful stuff behind your back like starting/committing
transactions.

regards, tom lane

---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Joost Kraaijeveld
On Fri, 2005-09-23 at 10:33 -0400, Tom Lane wrote:
 Is the client code running on the same machine as the database server?
 If not, what's the network delay and latency between them?
Yes, it is running on the same machine.


 The major problem you're going to have here is at least one network
 round trip per row inserted --- possibly more, if the jdbc driver is
 doing helpful stuff behind your back like starting/committing
 transactions.
OK, I will look into that.

But do you maybe know a pointer to info, or tools that can measure, what
my machine is doing during all the time it is doing nothing? Something
like the performance monitor in Windows but than for Linux?

-- 
Groeten,

Joost Kraaijeveld
Askesis B.V.
Molukkenstraat 14
6524NB Nijmegen
tel: 024-3888063 / 06-51855277
fax: 024-3608416
e-mail: [EMAIL PROTECTED]
web: www.askesis.nl 



---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faq


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Tom Lane
Joost Kraaijeveld [EMAIL PROTECTED] writes:
 But do you maybe know a pointer to info, or tools that can measure, what
 my machine is doing during all the time it is doing nothing? Something
 like the performance monitor in Windows but than for Linux?

top, vmstat, iostat, sar, strace, oprofile, ...

regards, tom lane

---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PERFORM] SELECT LIMIT 1 VIEW Performance Issue

2005-09-23 Thread K C Lau

Dear Merlin,

At 20:34 05/09/23, Merlin Moncure wrote:

Can you time just the execution of this function and compare vs. pure
SQL version?  If the times are different, can you do a exaplain analyze
of a prepared version of above?


esdt= prepare test(character varying) as select atdate from player where
esdt- playerid = $1 order by playerid desc, AtDate desc limit 1;
PREPARE
esdt= explain analyze execute test('0');
 Limit  (cost=0.00..0.83 rows=1 width=23) (actual time=0.032..0.033 rows=1 
loops=1)
   -  Index Scan Backward using pk_player on player  (cost=0.00..970.53 
rows=1166 width=23) (actual time=0.027..0.027 rows=1 loops=1)

 Index Cond: ((playerid)::text = ($1)::text)
 Total runtime: 0.088 ms

The prepared SQL timing is similar to that of a direct SQL.


 esdt= create or replace view VCurPlayer3 as select * from Player where
 AtDate = player_max_atdate(PlayerID);

This is wrong, it should have been
create or replace view VCurPlayer3 as select *,
player_max_atdate(PlayerID) as max_date  from Player;


Your suggestion returns all the records plus a max AtDate column for each 
PlayerID.
What I want to get with the view is the record that has the max value of 
AtDate for each PlayerID.
The AtDate is a varchar(23) field containing a string date of format 
'mmddhh', not the SQL Date field. Sorry if that confused you.



Something is not jiving here.  However, if the server plan still does
not come out correct, try the following (p.s. why is function returning
varchar(32) and not date?):


esdt= create or replace function player_max_atdate (varchar(32)) returns 
varchar(32) as $$

esdt$ DECLARE
esdt$player_record record;
esdt$return_date varchar(32);
esdt$ BEGIN
esdt$for player_record in execute
esdt$'select atdate from player where playerid = \'' || $1 || 
'\' order by playerid desc, AtDate desc limit 1;' loop

esdt$return_date = player_record.atdate;
esdt$end loop;
esdt$return return_date;
esdt$ END;
esdt$ $$ language plpgsql immutable;
CREATE FUNCTION
esdt= create or replace view VCurPlayer3 as select * from Player where 
AtDate = player_max_atdate(PlayerID);

CREATE VIEW
esdt= explain analyze select PlayerID,AtDate from VCurPlayer3 where 
PlayerID='0';


 Index Scan using pk_player on player  (cost=0.00..1331.83 rows=9 
width=23) (actual time=849.021..849.025 rows=1 loops=1)

   Index Cond: ((playerid)::text = '0'::text)
   Filter: ((atdate)::text = (player_max_atdate(playerid))::text)
 Total runtime: 849.078 ms

Your suggested plpgsql function seems to be even slower, with a best time 
of 849 ms after several tries. Is that expected?


Thanks again and best regards,
KC.


---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
  choose an index scan if your joining column's datatypes do not
  match


Re: [PERFORM] How to determine cause of performance problem?

2005-09-23 Thread Michael Stone

On Fri, Sep 23, 2005 at 03:49:25PM +0200, Joost Kraaijeveld wrote:
On Fri, 2005-09-23 at 07:05 -0400, Michael Stone wrote: 

Ok, that's great, but you didn't respond to the suggestion of using COPY
INTO instead of INSERT.

Part of the code I left out are some data conversions (e.g. from
path-to-file to blob, from text to date (not castable because of the
homebrew original format)). I don't believe that I can do these in a SQL
statement, can I (my knowledge of SQL as a langage is not that good)? .
However I will investigate if I can do the conversion in two steps and
check if it is faster.


I'm not sure what you're trying to say. 


You're currently putting rows into the table by calling INSERT INTO
for each row. The sample code you send could be rewritten to use COPY
INTO instead.  For bulk inserts like you're doing, the copy approach
will be a lot faster.  Instead of inserting one row, waiting for a
reply, and inserting the next row, you just cram data down a pipe to the
server.  


See:
http://www.postgresql.org/docs/8.0/interactive/sql-copy.html
http://www.faqs.org/docs/ppbook/x5504.htm

Mike Stone

---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

  http://www.postgresql.org/docs/faq


[PERFORM] slow database, queries accumulating

2005-09-23 Thread Anjan Dave








Hi



We are experiencing consistent slowness on the database for
one application. This is more a reporting type of application, heavy on the
bytea data type usage (gets rendered into PDFs in the app server). A lot of
queries, mostly selects and a few random updates, get accumulated on the server
 with increasing volume of users on the application. Below is a snapshot
of top, with about 80 selects and 3 or 4 updates. Things get better eventually if
I cancel (SIGINT) some of the oldest queries. I also see a few instances of
shared locks not being granted during this timeI dont even see high
iowait or memory starvation during these times, as indicated by top.



-bash-2.05b$ psql -c select * from pg_locks; dbname
| grep f

 | | 77922136 | 16761 |
ShareLock | f







We (development) are looking into the query optimization
(explain analyze, indexes, etc), and my understanding is that the queries when
run for explain analyze execute fast, but during busy times, they become quite
slow, taking from a few seconds to a few minutes to execute. I do see in the
log that almost all queries do have either ORDER BY, or GROUP BY, or DISTINCT.
Does it hurt to up the sort_mem to 3MB or 4MB? Should I up the
effective_cache_size to 5 or 6GB? The app is does not need a lot of connections
on the database, I can reduce it down from 600.



Based on the description above and the configuration below
does any thing appear bad in config? Is there anything I can try in the
configuration to improve performance?





The database size is about 4GB. 

This is PG 7.4.7, RHAS3.0 (u5), Local 4 spindle RAID10
(15KRPM), and logs on a separate set of drives, RAID10. 6650 server, 4 x XEON,
12GB RAM.

Vacuum is done every night, full vacuum done once a week.

I had increased the shared_buffers and sort_memory recently,
which didnt help.



Thanks,
Anjan









10:44:51 up 14 days, 13:38, 2 users, load average: 0.98,
1.14, 1.12

264 processes: 257 sleeping, 7 running, 0 zombie, 0 stopped

CPU states: cpu user nice system irq softirq
iowait idle

 total 14.4% 0.0% 7.4% 0.0% 0.0%
0.0% 77.9%

 cpu00 15.7% 0.0% 5.7% 0.0% 0.1%
0.0% 78.2%

 cpu01 15.1% 0.0% 7.5% 0.0% 0.0%
0.1% 77.0%

 cpu02 10.5% 0.0% 5.9% 0.0% 0.0%
0.0% 83.4%

 cpu03 9.9% 0.0% 5.9% 0.0% 0.0%
0.0% 84.0%

 cpu04 7.9% 0.0% 3.7% 0.0% 0.0%
0.0% 88.2%

 cpu05 19.3% 0.0% 12.3% 0.0% 0.0%
0.0% 68.3%

 cpu06 20.5% 0.0% 9.5% 0.0% 0.0%
0.1% 69.7%

 cpu07 16.1% 0.0% 8.5% 0.0% 0.1%
0.3% 74.7%

Mem: 12081736k av, 7881972k used, 4199764k free, 0k
shrd, 82372k buff

 4823496k actv, 2066260k in_d, 2036k
in_c

Swap: 4096532k av, 0k used, 4096532k
free 6888900k cached



 PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM
TIME CPU COMMAND

16773 postgres 15 0 245M 245M 240M S 0.0 2.0
1:16 7 postmaster

16880 postgres 15 0 245M 245M 240M S 0.1 2.0
0:49 6 postmaster

16765 postgres 15 0 245M 245M 240M S 0.0 2.0
1:16 0 postmaster

16825 postgres 15 0 245M 245M 240M S 0.0 2.0
1:02 5 postmaster

16774 postgres 15 0 245M 245M 240M S 0.1 2.0
1:16 0 postmaster

16748 postgres 15 0 245M 245M 240M S 0.0 2.0
1:19 5 postmaster

16881 postgres 15 0 245M 245M 240M S 0.1 2.0
0:50 7 postmaster

16762 postgres 15 0 245M 245M 240M S 0.0 2.0
1:14 4 postmaster









max_connections = 600



shared_buffers = 3 #=234MB, up from 21760=170MB min 16,
at least max_connections*2, 8KB each

sort_mem = 2048 # min 64, size in KB

vacuum_mem = 32768 # up from 16384 min 1024,
size in KB



# - Free Space Map -



#max_fsm_pages = 2 # min max_fsm_relations*16,
6 bytes each

#max_fsm_relations = 1000 # min 100, ~50 bytes each



#fsync = true # turns forced
synchronization on or off

#wal_sync_method = fsync # the default varies across
platforms:

 # fsync, fdatasync,
open_sync, or open_datasync

#wal_buffers = 8 # min 4, 8KB each



# - Checkpoints -



checkpoint_segments = 125 # in logfile segments, min
1, 16MB each

checkpoint_timeout = 600 # range 30-3600, in seconds

#checkpoint_warning = 30 # 0 is off, in seconds

#commit_delay = 0 # range 0-10, in
microseconds

#commit_siblings = 5 # range 1-1000







# - Planner Method Enabling -



#enable_hashagg = true

#enable_hashjoin = true

#enable_indexscan = true

#enable_mergejoin = true

#enable_nestloop = true

#enable_seqscan = true

#enable_sort = true

#enable_tidscan = true



# - Planner Cost Constants -



effective_cache_size = 262144 # =2GB typically 8KB each

#random_page_cost = 4 # units are one sequential
page fetch cost

#cpu_tuple_cost = 0.01 # (same)

#cpu_index_tuple_cost = 0.001 # (same)

#cpu_operator_cost = 0.0025 # (same)



# - Genetic Query Optimizer -



#geqo = true

#geqo_threshold = 11

#geqo_effort = 1

#geqo_generations = 0

#geqo_pool_size = 0 # default based on tables in
statement,

 # range 128-1024

#geqo_selection_bias = 2.0 # range 1.5-2.0



# - Other Planner Options -



#default_statistics_target = 10 # range 1-1000

#from_collapse_limit = 8

#join_collapse_limit = 8 # 1 disables collapsing of
explicit JOINs












Re: [PERFORM] VACUUM FULL vs CLUSTER

2005-09-23 Thread Stef
Bruno Wolff III mentioned :
= If you have a proper FSM setting you shouldn't need to do vacuum fulls
= (unless you have an older version of postgres where index bloat might
= be an issue).

What version of postgres was the last version that had
the index bloat problem?

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
   choose an index scan if your joining column's datatypes do not
   match


Re: [PERFORM] tsearch2 seem very slow

2005-09-23 Thread Ahmad Fajar
Hi Oleg,

For single index I try this query:
explain analyze 
select articleid, title, datee from articles
where fti @@ to_tsquery('bankindonesia');

analyze result:

Index Scan using fti_idx on articles  (cost=0.00..862.97 rows=420 width=51)
(actual time=0.067..183761.324 rows=46186 loops=1)
  Index Cond: (fti @@ '\'bank\'  \'indonesia\''::tsquery)
Total runtime: 183837.826 ms

And for multicolumn index I try this query:
explain analyze 
select articleid, title, datee from articles
where fti @@ to_tsquery('bankmega');

analyze result:

Index Scan using articles_x1 on articles  (cost=0.00..848.01 rows=410
width=51) (actual time=52.204..37914.135 rows=1841 loops=1)
  Index Cond: ((datee = '2002-01-01'::date) AND (datee =
('now'::text)::date) AND (fti @@ '\'bank\'  \'mega\''::tsquery))
Total runtime: 37933.757 ms

The table structure is as mention on the first talk. If you wanna know how
much table in my database, it's about 100 tables or maybe more. Now I
develop the version 2 of my web application, you can take a look at:
http://www.mediatrac.net, so it will hold many datas. But the biggest table
is article's table. On develop this version 2 I just use half data of the
article's table (about 419804 rows). May be if I import all of the article's
table data it will have 1 million rows. The article's table grows rapidly,
about 10 rows per-week. My developing database size is 28 GB (not real
database, coz I still develop the version 2 and I use half of the data for
play around). I just wanna to perform quick search (fulltext search) on my
article's table not other table. On version 1, the current running version I
use same hardware spesification as mention below, but there is no fulltext
search. So I develop the new version with new features, new interface and
include the fulltext search.

I do know, if the application finish, I must use powerfull hardware. But how
can I guarantee the application will run smooth, if I do fulltext search on
419804 rows in a table it took a long time to get the result. 

Could you or friends in this maling-list help meplz..plzz

Tsearch2 configuration:
-
I use default configuration, english stop word file as tsearch2 provide,
stem dictionary as default (coz I don't know how to configure and add new
data to stem dictionary) and I add some words to the english stop word file.

Postgresql configuration
-
max_connections = 32
shared_buffers = 32768
sort_mem = 8192
vacuum_mem = 65536
work_mem = 16384
maintenance_work_mem = 65536
max_fsm_pages = 3
max_fsm_relations = 1000
max_files_per_process = 10
checkpoint_segments = 15
effective_cache_size = 192000
random_page_cost = 2
geqo = true
geqo_threshold = 50
geqo_effort = 5
geqo_pool_size = 0
geqo_generations = 0
geqo_selection_bias = 2.0
from_collapse_limit = 10
join_collapse_limit = 15

OS configuration:
--
I use Redhat 4 AS, kernel 2.6.9-11
kernel.shmmax=1073741824
kernel.sem=250 32000 100 128
fs.aio-max-nr=5242880
the server I configure just only for postgresql, no other service is running
like: www, samba, ftp, email, firewall 

hardware configuration:

Motherboard ASUS P5GD1
Processor P4 3,2 GHz
Memory 2 GB DDR 400, 
2x200 GB Serial ATA 7200 RPM UltraATA/133, configure as RAID0 for postgresql
data and the partition is EXT3
1x80 GB EIDE 7200 RPM configure for system and home directory and the
partiton is EXT3

Did I miss something?

Regards,
ahmad fajar


-Original Message-
From: Oleg Bartunov [mailto:[EMAIL PROTECTED] 
Sent: Jumat, 23 September 2005 18:26
To: Ahmad Fajar
Cc: pgsql-performance@postgresql.org
Subject: RE: [PERFORM] tsearch2 seem very slow

On Fri, 23 Sep 2005, Ahmad Fajar wrote:

 Hi Oleg,

 I didn't deny on the third repeat or more, it can reach  600 msec. It is
 only because the result still in postgres cache, but how about in the
first
 run? I didn't dare, the values is un-acceptable. Because my table will
grows
 rapidly, it's about 10 rows per-week. And the visitor will search
 anything that I don't know, whether it's the repeated search or new
search,
 or whether it's in postgres cache or not.

if you have enoush shared memory postgresql will keep index pages there.



 I just compare with http://www.postgresql.org, the search is quite fast,
and
 I don't know whether the site uses tsearch2 or something else. But as fas
as
 I know, if the rows reach 100 milion (I have try for 200 milion rows and
it
 seem very slow), even if don't use tsearch2, only use simple query like:
 select f1, f2 from table1 where f2='blabla',
 and f2 is indexes, my postgres still slow on the first time, about 10
sec.
 because of this I tried something brand new to fullfill my needs. I have
 used fti, and tsearch2 but still slow.

 I don't know what's going wrong with my postgres, what configuration must
I
 do to perform the query get fast result. Or must I use enterprisedb 2005
or
 pervasive 

Re: [PERFORM] VACUUM FULL vs CLUSTER

2005-09-23 Thread Alvaro Herrera
On Fri, Sep 23, 2005 at 06:16:44PM +0200, Stef wrote:
 Bruno Wolff III mentioned :
 = If you have a proper FSM setting you shouldn't need to do vacuum fulls
 = (unless you have an older version of postgres where index bloat might
 = be an issue).
 
 What version of postgres was the last version that had
 the index bloat problem?

The worst problems were solved in 7.4.  There are problems in certain
limited circumstances even with current releases.

-- 
Alvaro Herrera  http://www.amazon.com/gp/registry/DXLWNGRJD34
The ability to monopolize a planet is insignificant
next to the power of the source

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly


Re: [PERFORM] VACUUM FULL vs CLUSTER

2005-09-23 Thread Bruno Wolff III
On Fri, Sep 23, 2005 at 18:16:44 +0200,
  Stef [EMAIL PROTECTED] wrote:
 Bruno Wolff III mentioned :
 = If you have a proper FSM setting you shouldn't need to do vacuum fulls
 = (unless you have an older version of postgres where index bloat might
 = be an issue).
 
 What version of postgres was the last version that had
 the index bloat problem?

You can check the release notes to be sure, but my memory is that the
unbounded bloat problem was fixed in 7.4. There still are usage patterns
that can result in bloating, but it is limited to some constant multiplier
of the minimum index size.

---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PERFORM] Query slower on 8.0.3 (Windows) vs 7.3 (cygwin)

2005-09-23 Thread Gurpreet Aulakh
After further investigation I have found that the reason why the query is
slower on 8.0.3 is that the hash and hash joins are slower on the 8.0.3.

So the question comes down to : Why are hash and hash joins slower? Is this
a postgres configuration setting that I am missing? Is the locale still
screwing me up? I have set the locale to 'C' without any improvements. Is it
because the column type is a varchar that the hash is slower?




---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PERFORM] VACUUM FULL vs CLUSTER

2005-09-23 Thread Stef

Bruno Wolff III mentioned :
=  = If you have a proper FSM setting you shouldn't need to do vacuum fulls
=  = (unless you have an older version of postgres where index bloat might
=  = be an issue).

Thanks Alvaro and Bruno

I just want to clarify something that I also couldn't 
find a clear cut answer for before. 

What is a proper fsm setting? 

Someone told me to set max_fsm_relations to the number of
relations in pg_class plus a few more to allow for new relations.
And max_fsm_pages to the number of rows in the biggest table I
want to vacuum, plus a few 1000's for extra room?

Where does this free space map sit? On the disk somewhere,
or in memory, or both.

I once set the max_fsm_pages very high by mistake, and postgres
then started up and used a _lot_ of shared memory, and I had to
increase shmmax. Is there abything to watch out for when bumping this
setting up a lot?

Kind Regards
Stefan  

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [PERFORM] Releasing memory during External sorting?

2005-09-23 Thread Tom Lane
Ron Peacetree [EMAIL PROTECTED] writes:
 2= No optimal external sorting algorithm should use more than 2 passes.
 3= Optimal external sorting algorithms should use 1 pass if at all possible.

A comparison-based sort must use at least N log N operations, so it
would appear to me that if you haven't got approximately log N passes
then your algorithm doesn't work.

regards, tom lane

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
   choose an index scan if your joining column's datatypes do not
   match


Re: [PERFORM] Releasing memory during External sorting?

2005-09-23 Thread Mark Lewis
operations != passes.  If you were clever, you could probably write a
modified bubble-sort algorithm that only made 2 passes.  A pass is a
disk scan, operations are then performed (hopefully in memory) on what
you read from the disk.  So there's no theoretical log N lower-bound on
the number of disk passes.

Not that I have anything else useful to add to this discussion, just a
tidbit I remembered from my CS classes back in college :)

-- Mark

On Fri, 2005-09-23 at 13:17 -0400, Tom Lane wrote:
 Ron Peacetree [EMAIL PROTECTED] writes:
  2= No optimal external sorting algorithm should use more than 2 passes.
  3= Optimal external sorting algorithms should use 1 pass if at all possible.
 
 A comparison-based sort must use at least N log N operations, so it
 would appear to me that if you haven't got approximately log N passes
 then your algorithm doesn't work.
 
   regards, tom lane
 
 ---(end of broadcast)---
 TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match


---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PERFORM] VACUUM FULL vs CLUSTER

2005-09-23 Thread Chris Browne
[EMAIL PROTECTED] (Stef) writes:
 Bruno Wolff III mentioned :
 = If you have a proper FSM setting you shouldn't need to do vacuum fulls
 = (unless you have an older version of postgres where index bloat might
 = be an issue).

 What version of postgres was the last version that had
 the index bloat problem?

I believe that was fixed in 7.3; it was certainly resolved by 7.4...
-- 
(format nil [EMAIL PROTECTED] cbbrowne cbbrowne.com)
http://www.ntlug.org/~cbbrowne/spiritual.html
MICROS~1 has  brought the  microcomputer OS to  the point where  it is
more bloated than even OSes from what was previously larger classes of
machines   altogether.   This  is   perhaps  Bill's   single  greatest
accomplishment.

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly


Re: [PERFORM] Releasing memory during External sorting?

2005-09-23 Thread Tom Lane
Mark Lewis [EMAIL PROTECTED] writes:
 operations != passes.  If you were clever, you could probably write a
 modified bubble-sort algorithm that only made 2 passes.  A pass is a
 disk scan, operations are then performed (hopefully in memory) on what
 you read from the disk.  So there's no theoretical log N lower-bound on
 the number of disk passes.

Given infinite memory that might be true, but I don't think I believe it
for limited memory.  If you have room for K tuples in memory then it's
impossible to perform more than K*N useful comparisons per pass (ie, as
each tuple comes off the disk you can compare it to all the ones
currently in memory; anything more is certainly redundant work).  So if
K  logN it's clearly not gonna work.

It's possible that you could design an algorithm that works in a fixed
number of passes if you are allowed to assume you can hold O(log N)
tuples in memory --- and in practice that would probably work fine,
if the constant factor implied by the O() isn't too big.  But it's not
really solving the general external-sort problem.

regards, tom lane

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PERFORM] Releasing memory during External sorting?

2005-09-23 Thread Ron Peacetree
Yep.  Also, bear in mind that the lg(n!)= ~ nlgn - n lower bound on
the number of comparisions:
a= says nothing about the amount of data movement used.
b= only holds for generic comparison based sorting algorithms.

As Knuth says (vol 3, p180), Distribution Counting sorts without
ever comparing elements to each other at all, and so does Radix
Sort.  Similar comments can be found in many algorithms texts.

Any time we know that the range of the data to be sorted is substantially
restricted compared to the number of items to be sorted, we can sort in
less than O(lg(n!)) time.  DB fields tend to take on few values and are
therefore substantially restricted.

Given the proper resources and algorithms, O(n) sorts are very plausible
when sorting DB records.

All of the fastest external sorts of the last decade or so take advantage of
this.  Check out that URL I posted.

Ron


-Original Message-
From: Mark Lewis [EMAIL PROTECTED]
Sent: Sep 23, 2005 1:43 PM
To: Tom Lane [EMAIL PROTECTED]
Subject: Re: [PERFORM] Releasing memory during External sorting?

operations != passes.  If you were clever, you could probably write a
modified bubble-sort algorithm that only made 2 passes.  A pass is a
disk scan, operations are then performed (hopefully in memory) on what
you read from the disk.  So there's no theoretical log N lower-bound on
the number of disk passes.

Not that I have anything else useful to add to this discussion, just a
tidbit I remembered from my CS classes back in college :)

-- Mark

On Fri, 2005-09-23 at 13:17 -0400, Tom Lane wrote:
 Ron Peacetree [EMAIL PROTECTED] writes:
  2= No optimal external sorting algorithm should use more than 2 passes.
  3= Optimal external sorting algorithms should use 1 pass if at all possible.
 
 A comparison-based sort must use at least N log N operations, so it
 would appear to me that if you haven't got approximately log N passes
 then your algorithm doesn't work.
 
   regards, tom lane

---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [PERFORM] Releasing memory during External sorting?

2005-09-23 Thread Ron Peacetree
From: Tom Lane [EMAIL PROTECTED]
Sent: Sep 23, 2005 2:15 PM
Subject: Re: [PERFORM] Releasing memory during External sorting? 

Mark Lewis [EMAIL PROTECTED] writes:
 operations != passes.  If you were clever, you could probably write a
 modified bubble-sort algorithm that only made 2 passes.  A pass is a
 disk scan, operations are then performed (hopefully in memory) on what
 you read from the disk.  So there's no theoretical log N lower-bound on
 the number of disk passes.

Given infinite memory that might be true, but I don't think I believe it
for limited memory.  If you have room for K tuples in memory then it's
impossible to perform more than K*N useful comparisons per pass (ie, as
each tuple comes off the disk you can compare it to all the ones
currently in memory; anything more is certainly redundant work).  So if
K  logN it's clearly not gonna work.

Actually, it's far better than that.  I recall a paper I saw in one of the
algorithms journals 15+ years ago that proved that if you knew the range
of the data, regardless of what that range was, and had n^2 space, you
could sort n items in O(n) time.

Turns out that with very modest constraints on the range of the data and
substantially less extra space (about the same as you'd need for
Replacement Selection + External Merge Sort), you can _still_ sort in
O(n) time.


It's possible that you could design an algorithm that works in a fixed
number of passes if you are allowed to assume you can hold O(log N)
tuples in memory --- and in practice that would probably work fine,
if the constant factor implied by the O() isn't too big.  But it's not
really solving the general external-sort problem.

If you know nothing about the data to be sorted and must guard against
the worst possible edge cases, AKA the classic definition of the general
external sorting problem,  then one can't do better than some variant
of Replacement Selection + Unbalanced Multiway Merge.

OTOH, ITRW things are _not_ like that.  We know the range of the data
in our DB fields or we can safely assume it to be relatively constrained.
This allows us access to much better external sorting algorithms.

For example Postman Sort (the 2005 winner of the PennySort benchmark)
is basically an IO optimized version of an external Radix Sort.


Ron

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PERFORM] Query slower on 8.0.3 (Windows) vs 7.3 (cygwin)

2005-09-23 Thread Tom Lane
Gurpreet Aulakh [EMAIL PROTECTED] writes:
 After further investigation I have found that the reason why the query is
 slower on 8.0.3 is that the hash and hash joins are slower on the 8.0.3.
 So the question comes down to : Why are hash and hash joins slower?

I looked into this a bit and determined that the problem seems to have
been introduced here:

2002-12-30 10:21  tgl

* src/: backend/executor/nodeHash.c,
backend/executor/nodeHashjoin.c, backend/optimizer/path/costsize.c,
include/executor/nodeHash.h: Better solution to integer overflow
problem in hash batch-number computation: reduce the bucket number
mod nbatch.  This changes the association between original bucket
numbers and batches, but that doesn't matter.  Minor other cleanups
in hashjoin code to help centralize decisions.

(which means it's present in 7.4 as well as 8.0).  The code now
groups tuples into hash batches according to
(hashvalue % totalbuckets) % nbatch
When a tuple that is not in the first batch is reloaded, it is placed
into a bucket according to
(hashvalue % nbuckets)
This means that if totalbuckets, nbatch, and nbuckets have a common
factor F, the buckets won't be evenly used; in fact, only one in every F
buckets will be used at all, the rest remaining empty.  The ones that
are used accordingly will contain about F times more tuples than
intended.  The slowdown comes from having to compare these extra tuples
against the outer-relation tuples.

7.3 uses a different algorithm for grouping tuples that avoids this
problem, but it has performance issues of its own (in particular, to
avoid integer overflow we have to limit the number of batches we can
have).  So just reverting this patch doesn't seem very attractive.

The problem no longer exists in 8.1 because of rewrites undertaken for
another purpose, so I'm sort of tempted to do nothing.  To fix this in
the back branches we'd have to develop new code that won't ever go into
CVS tip and thus will never get beta-tested.  The risk of breaking
things seems higher than I'd like.

If we did want to fix it, my first idea is to increment nbatch looking
for a value that has no common factor with nbuckets.

regards, tom lane

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


[PERFORM] Index use in BETWEEN statement...

2005-09-23 Thread Cristian Prieto
Hello pals, I have the following table in Postgresql 8.0.1

Mydb# \d geoip_block
Table public.geoip_block
   Column|  Type  | Modifiers
-++---
 locid   | bigint |
 start_block | inet   |
 end_block   | inet   |

mydb# explain analyze select locid from geoip_block where
'216.230.158.50'::inet between start_block and end_block;
  QUERY PLAN

---
 Seq Scan on geoip_block  (cost=0.00..142772.86 rows=709688 width=8) (actual
time=14045.384..14706.927 rows=1 loops=1)
   Filter: (('216.230.158.50'::inet = start_block) AND
('216.230.158.50'::inet = end_block))
 Total runtime: 14707.038 ms

Ok, now I decided to create a index to speed a little the query

Mydb# create index idx_ipblocks on geoip_block(start_block, end_block);
CREATE INDEX

clickad=# explain analyze select locid from geoip_block where
'216.230.158.50'::inet between start_block and end_block;
  QUERY PLAN

--
 Seq Scan on geoip_block  (cost=0.00..78033.96 rows=230141 width=8) (actual
time=12107.919..12610.199 rows=1 loops=1)
   Filter: (('216.230.158.50'::inet = start_block) AND
('216.230.158.50'::inet = end_block))
 Total runtime: 12610.329 ms
(3 rows)

I guess the planner is doing a sequential scan in the table, why not use the
compound index? Do you have any idea in how to speed up this query?

Thanks a lot!


---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [PERFORM] SELECT LIMIT 1 VIEW Performance Issue

2005-09-23 Thread Mark Kirkwood

K C Lau wrote:
Thank you all for your suggestions. I' tried, with some variations too, 
but still no success. The times given are the best of a few repeated 
tries on an 8.1 beta 2 db freshly migrated from 8.0.3 on Windows.




A small denormalization, where you mark the row with the latest atdate 
for each playerid may get you the performance you want.


e.g: (8.1beta1)

ALTER TABLE player ADD islastatdate boolean;

UPDATE player SET islastatdate = true where (playerid,atdate) IN
(SELECT playerid, atdate FROM vcurplayer);

CREATE OR REPLACE VIEW vcurplayer AS
SELECT * FROM player a
WHERE islastatdate;

CREATE INDEX player_id_lastatdate ON player(playerid, islastatdate)
WHERE islastatdate;

ANALYZE player;

Generating some test data produced:

EXPLAIN ANALYZE
SELECT playerid,atdate
FROM vcurplayer
WHERE playerid='0';

   QUERY PLAN 



 Index Scan using player_id_lastatdate on player a  (cost=0.00..4.33 
rows=1 width=13) (actual time=0.142..0.149 rows=1 loops=1)

   Index Cond: ((playerid = '0'::text) AND (lastatdate = true))
   Filter: lastatdate
 Total runtime: 0.272 ms
(4 rows)

Whereas with the original view definition:

CREATE OR REPLACE VIEW vcurplayer AS
SELECT * FROM player a
WHERE a.atdate =
( SELECT max(b.atdate) FROM player b
  WHERE a.playerid = b.playerid);

EXPLAIN ANALYZE
SELECT playerid,atdate
FROM vcurplayer
WHERE playerid='0';

QUERY PLAN 


-
 Index Scan using player_id_date on player a  (cost=0.00..7399.23 
rows=11 width=13) (actual time=121.738..121.745 rows=1 loops=1)

   Index Cond: (playerid = '0'::text)
   Filter: (atdate = (subplan))
   SubPlan
 -  Result  (cost=1.72..1.73 rows=1 width=0) (actual 
time=0.044..0.047 rows=1 loops=2000)

   InitPlan
 -  Limit  (cost=0.00..1.72 rows=1 width=4) (actual 
time=0.028..0.031 rows=1 loops=2000)
   -  Index Scan Backward using player_id_date on 
player b  (cost=0.00..3787.94 rows=2198 width=4) (actual 
time=0.019..0.019 rows=1 loops=2000)

 Index Cond: ($0 = playerid)
 Filter: (atdate IS NOT NULL)
 Total runtime: 121.916 ms
(11 rows)

Note that my generated data has too many rows for each playerid, but the 
 difference in performance should illustrate the idea.


Cheers

Mark

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
  choose an index scan if your joining column's datatypes do not
  match


Re: [PERFORM] SELECT LIMIT 1 VIEW Performance Issue

2005-09-23 Thread K C Lau

Dear Mark,

Thank you. That seems like a more manageable alternative if nothing else 
works out. It should cover many of the OLTP update transactions. But it 
does mean quite a bit of programming changes and adding another index on 
all such tables, and it would not cover those cases when we need to get the 
latest record before a certain time, for example.


I'm wondering if this performance issue is common enough for other users to 
merit a fix in pg, especially as it seems that with MVCC, each of the data 
records need to be accessed in addition to scanning the index.


Best regards,
KC.

At 09:40 05/09/24, Mark Kirkwood wrote:
A small denormalization, where you mark the row with the latest atdate for 
each playerid may get you the performance you want.


e.g: (8.1beta1)

ALTER TABLE player ADD islastatdate boolean;

UPDATE player SET islastatdate = true where (playerid,atdate) IN
(SELECT playerid, atdate FROM vcurplayer);

CREATE OR REPLACE VIEW vcurplayer AS
SELECT * FROM player a
WHERE islastatdate;

CREATE INDEX player_id_lastatdate ON player(playerid, islastatdate)
WHERE islastatdate;

ANALYZE player;

Generating some test data produced:

EXPLAIN ANALYZE
SELECT playerid,atdate
FROM vcurplayer
WHERE playerid='0';

   QUERY PLAN

 Index Scan using player_id_lastatdate on player a  (cost=0.00..4.33 
rows=1 width=13) (actual time=0.142..0.149 rows=1 loops=1)

   Index Cond: ((playerid = '0'::text) AND (lastatdate = true))
   Filter: lastatdate
 Total runtime: 0.272 ms
(4 rows)

Whereas with the original view definition:

CREATE OR REPLACE VIEW vcurplayer AS
SELECT * FROM player a
WHERE a.atdate =
( SELECT max(b.atdate) FROM player b
  WHERE a.playerid = b.playerid);

EXPLAIN ANALYZE
SELECT playerid,atdate
FROM vcurplayer
WHERE playerid='0';
QUERY PLAN
-
 Index Scan using player_id_date on player a  (cost=0.00..7399.23 rows=11 
width=13) (actual time=121.738..121.745 rows=1 loops=1)

   Index Cond: (playerid = '0'::text)
   Filter: (atdate = (subplan))
   SubPlan
 -  Result  (cost=1.72..1.73 rows=1 width=0) (actual 
time=0.044..0.047 rows=1 loops=2000)

   InitPlan
 -  Limit  (cost=0.00..1.72 rows=1 width=4) (actual 
time=0.028..0.031 rows=1 loops=2000)
   -  Index Scan Backward using player_id_date on player 
b  (cost=0.00..3787.94 rows=2198 width=4) (actual time=0.019..0.019 
rows=1 loops=2000)

 Index Cond: ($0 = playerid)
 Filter: (atdate IS NOT NULL)
 Total runtime: 121.916 ms
(11 rows)

Note that my generated data has too many rows for each playerid, but 
the  difference in performance should illustrate the idea.


Cheers

Mark



---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
  choose an index scan if your joining column's datatypes do not
  match


Re: [PERFORM] SELECT LIMIT 1 VIEW Performance Issue

2005-09-23 Thread Mark Kirkwood

K C Lau wrote:

I'm wondering if this performance issue is common enough for other users 
to merit a fix in pg, especially as it seems that with MVCC, each of the 
data records need to be accessed in addition to scanning the index.




Yes - there are certainly cases where index only access (or something 
similar, like b+tree tables) would be highly desirable.


From what I have understood from previous discussions, there are 
difficulties involved with producing a design that does not cause new 
problems...


regards

Mark

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
  subscribe-nomail command to [EMAIL PROTECTED] so that your
  message can get through to the mailing list cleanly


Re: [PERFORM] [HACKERS] Releasing memory during External sorting?

2005-09-23 Thread Tom Lane
Simon Riggs [EMAIL PROTECTED] writes:
 If not, I would propose that when we move from qsort to tapesort mode we
 free the larger work_mem setting (if one exists) and allocate only a
 lower, though still optimal setting for the tapesort. That way the
 memory can be freed for use by other users or the OS while the tapesort
 proceeds (which is usually quite a while...).

On most platforms it's quite unlikely that any memory would actually get
released back to the OS before transaction end, because the memory
blocks belonging to the tuplesort context will be intermixed with blocks
belonging to other contexts.  So I think this is pretty pointless.
(If you can't afford to have the sort using all of sort_mem, you've set
sort_mem too large, anyway.)

regards, tom lane

---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [PERFORM] [HACKERS] Releasing memory during External sorting?

2005-09-23 Thread Simon Riggs
On Fri, 2005-09-23 at 10:09 -0400, Tom Lane wrote:
 Simon Riggs [EMAIL PROTECTED] writes:
  If not, I would propose that when we move from qsort to tapesort mode we
  free the larger work_mem setting (if one exists) and allocate only a
  lower, though still optimal setting for the tapesort. That way the
  memory can be freed for use by other users or the OS while the tapesort
  proceeds (which is usually quite a while...).
 
 On most platforms it's quite unlikely that any memory would actually get
 released back to the OS before transaction end, because the memory
 blocks belonging to the tuplesort context will be intermixed with blocks
 belonging to other contexts.  So I think this is pretty pointless.

I take it you mean pointless because of the way the memory allocation
works, rather than because giving memory back isn't worthwhile ?

Surely the sort memory would be allocated in contiguous chunks? In some
cases we might be talking about more than a GB of memory, so it'd be
good to get that back ASAP. I'm speculating

 (If you can't afford to have the sort using all of sort_mem, you've set
 sort_mem too large, anyway.)

Sort takes care to allocate only what it needs as starts up. All I'm
suggesting is to take the same care when the sort mode changes. If the
above argument held water then we would just allocate all the memory in
one lump at startup, because we can afford to, so I don't buy that. 

Since we know the predicted size of the sort set prior to starting the
sort node, could we not use that information to allocate memory
appropriately? i.e. if sort size is predicted to be more than twice the
size of work_mem, then just move straight to the external sort algorithm
and set the work_mem down at the lower limit?

That is, unless somebody has evidence that having a very large memory
has any performance benefit for external sorting?

Best Regards, Simon Riggs





---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faq


Re: [PERFORM] [HACKERS] Releasing memory during External sorting?

2005-09-23 Thread Tom Lane
Simon Riggs [EMAIL PROTECTED] writes:
 Since we know the predicted size of the sort set prior to starting the
 sort node, could we not use that information to allocate memory
 appropriately? i.e. if sort size is predicted to be more than twice the
 size of work_mem, then just move straight to the external sort algorithm
 and set the work_mem down at the lower limit?

Have you actually read the sort code?

During the run-forming phase it's definitely useful to eat all the
memory you can: that translates directly to longer initial runs and
hence fewer merge passes.  During the run-merging phase it's possible
that using less memory would not hurt performance any, but as already
stated, I don't think it will actually end up cutting the backend's
memory footprint --- the sbrk point will be established during the run
forming phase and it's unlikely to move back much until transaction end.

Also, if I recall the development of that code correctly, the reason for
using more than minimum memory during the merge phase is that writing or
reading lots of tuples at once improves sequentiality of access to the
temp files.  So I'm not sure that cutting down the memory wouldn't hurt
performance.

regards, tom lane

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [PERFORM] Releasing memory during External sorting?

2005-09-23 Thread Ron Peacetree
From: Simon Riggs [EMAIL PROTECTED]
Sent: Sep 23, 2005 5:37 AM
Subject: [PERFORM] Releasing memory during External sorting?

I have concerns about whether we are overallocating memory for use in
external sorts. (All code relating to this is in tuplesort.c)

A decent external sorting algorithm, say a Merge Sort + Radix (or
Distribution Counting) hybrid with appropriate optimizations for small sub-
files, should become more effective / efficient the more RAM you give it. 


The external sort algorithm benefits from some memory but not much.

That's probably an artifact of the psql external sorting code and _not_
due to some fundamental external sorting issue.


Knuth says that the amount of memory required is very low, with a value
typically less than 1 kB.

Required means the external sort can operate on that little memory.  How
Much memory is required for optimal performance is another matter.


I/O overheads mean that there is benefit from having longer sequential
writes, so the optimum is much larger than that. I've not seen any data
that indicates that a setting higher than 16 MB adds any value at all to a 
large external sort.

It should.  A first pass upper bound would be the amount of RAM needed for
Replacement Selection to create a run (ie sort) of the whole file.  That should
be ~ the amount of RAM to hold 1/2 the file in a Replacement Selection pass.

At the simplest, for any file over 32MB the optimum should be more than 
16MB.


 I have some indications from private tests that very high memory settings
may actually hinder performance of the sorts, though I cannot explain that
and wonder whether it is the performance tests themselves that have issues.

Hmmm.  Are you talking about amounts so high that you are throwing the OS
into paging and swapping thrash behavior?  If not, then the above is weird.


Does anyone have any clear data that shows the value of large settings
of work_mem when the data to be sorted is much larger than memory? (I am
well aware of the value of setting work_mem higher for smaller sorts, so
any performance data needs to reflect only very large sorts). 

This is not PostgreSQL specific, but it does prove the point that the 
performance
of external sorts benefits greatly from large amounts of RAM being available:

http://research.microsoft.com/barc/SortBenchmark/

Looking at the particulars of the algorithms listed there should shed a lot of 
light
on what a good external sorting algorithm looks like:
1= HD IO matters the most.
 1a= Seeking behavior is the largest factor in poor performance.
2= No optimal external sorting algorithm should use more than 2 passes.
3= Optimal external sorting algorithms should use 1 pass if at all possible.
4= Use as much RAM as possible, and use it as efficiently as possible.
5= The amount of RAM needed to hide the latency of a HD subsytem goes up as
the _square_ of the difference between the bandwidth of the HD subsystem and
memory.
6= Be cache friendly.
7= For large numbers of records whose sorting key is substantially smaller than
the record itself, use a pointer + compressed key representation and write the 
data
to HD in sorted order (Replace HD seeks with RAM seeks.  Minimize RAM seeks).
8= Since your performance will be constrained by HD IO first and RAM IO second,
up to a point it is worth it to spend more CPU cycles to save on IO.

Given the large and growing gap between CPU IO, RAM IO, and HD IO, these issues
are becoming more important for _internal_ sorts as well.  


Feedback, please.

Best Regards, Simon Riggs

Hope this is useful,
Ron

---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org