Re: [PERFORM] Slow functional indexes?

2006-11-05 Thread Stuart Bishop
Stuart Bishop wrote:
 I would like to understand what causes some of my indexes to be slower to
 use than others with PostgreSQL 8.1. On a particular table, I have an int4
 primary key, an indexed unique text 'name' column and a functional index of
 type text. The function (person_sort_key()) is declared IMMUTABLE and
 RETURNS NULL ON NULL INPUT.
 
 A simple query ordering by each of these columns generates nearly identical
 query plans, however runtime differences are significantly slower using the
 functional index. If I add a new column to the table containing the result
 of the function, index it and query ordering by this new column then the
 runtime is nearly an order of magnitude faster than using the functional
 index (and again, query plans are nearly identical).

 (The following log is also at
 http://rafb.net/paste/results/vKVuyi47.nln.html if that is more readable)

Here is a minimal test case that demonstrates the issue. Can anyone else
reproduce these results? Of the four EXPLAIN ANALYZE SELECT statements at
the end, the one that orders by a user created IMMUTABLE stored procedure is
consistently slower than the other three variants.


BEGIN;
DROP TABLE TestCase;
COMMIT;
ABORT;

BEGIN;
CREATE TABLE TestCase (name text, alt_name text);

CREATE OR REPLACE FUNCTION munge(s text) RETURNS text
IMMUTABLE RETURNS NULL ON NULL INPUT
LANGUAGE plpgsql AS $$
BEGIN
RETURN lower(s);
END;
$$;

-- Fill the table with random strings
CREATE OR REPLACE FUNCTION fill_testcase(num_rows int) RETURNS boolean
LANGUAGE plpgsql AS
$$
DECLARE
row_num int;
char_num int;
name text;
BEGIN
FOR row_num IN 1..num_rows LOOP
name := '';
FOR  char_num IN 1..round(random() * 100) LOOP
name := name || chr((
round(random() * (ascii('z') - ascii('!'))) + ascii('!')
)::int);
END LOOP;
INSERT INTO TestCase VALUES (name, lower(name));
IF row_num % 2 = 0 THEN
RAISE NOTICE '% of % rows inserted', row_num, num_rows;
END IF;
END LOOP;
RETURN TRUE;
END;
$$;

SELECT fill_testcase(50);

CREATE INDEX testcase__name__idx ON TestCase(name);
CREATE INDEX testcase__lower__idx ON TestCase(lower(name));
CREATE INDEX testcase__munge__idx ON TestCase(munge(name));
CREATE INDEX testcase__alt_name__idx ON TestCase(alt_name);

COMMIT;

ANALYZE TestCase;

EXPLAIN ANALYZE SELECT * FROM TestCase ORDER BY name;
EXPLAIN ANALYZE SELECT * FROM TestCase ORDER BY lower(name);
EXPLAIN ANALYZE SELECT * FROM TestCase ORDER BY munge(name);
EXPLAIN ANALYZE SELECT * FROM TestCase ORDER BY alt_name;

EXPLAIN ANALYZE SELECT * FROM TestCase ORDER BY name;
EXPLAIN ANALYZE SELECT * FROM TestCase ORDER BY lower(name);
EXPLAIN ANALYZE SELECT * FROM TestCase ORDER BY munge(name);
EXPLAIN ANALYZE SELECT * FROM TestCase ORDER BY alt_name;


-- 
Stuart Bishop [EMAIL PROTECTED]
http://www.stuartbishop.net/



signature.asc
Description: OpenPGP digital signature


Re: [PERFORM] Slow functional indexes?

2006-11-05 Thread Tom Lane
Stuart Bishop [EMAIL PROTECTED] writes:
 Here is a minimal test case that demonstrates the issue. Can anyone else
 reproduce these results? Of the four EXPLAIN ANALYZE SELECT statements at
 the end, the one that orders by a user created IMMUTABLE stored procedure is
 consistently slower than the other three variants.

Wow, interesting.  I'm surprised we never realized this before, but
here's the deal: the generated plan computes the ORDER BY expressions
even if we end up not needing them because the ordering is created by
an indexscan rather than an explicit sort step.  (Such a sort step would
of course need the values as input.)  So the differential you're seeing
represents the time for all those useless evaluations of the function.
The difference in the estimated cost comes from that too --- the code
doing the estimation can see perfectly well that there's an extra
function call in the plan ...

Not sure whether there's a simple way to fix this; it might take some
nontrivial rejiggering in the planner.  Or maybe not, but I don't have
any cute ideas about it at the moment.

I wonder whether there are any other cases where we are doing useless
computations of resjunk columns?

regards, tom lane

---(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] Slow functional indexes?

2006-11-05 Thread Gene
I have a varchar field which is most commonly queried like someField like '%abcd'. Realizing that it wouldn't be able to use an index for this type of query I created a reverse() function and an index using the function reverse(someField) so that the query would be performed as reverse(someField) like reverse('%abcd'). When I looked at the query plan it seemed like it was using the new reverse index properly but also seemed to run slower. Would this explain these bazaar results? I have since gone back to the method without using the reverse function. Thanks
On 11/5/06, Tom Lane [EMAIL PROTECTED] wrote:
Stuart Bishop [EMAIL PROTECTED] writes: Here is a minimal test case that demonstrates the issue. Can anyone else reproduce these results? Of the four EXPLAIN ANALYZE SELECT statements at
 the end, the one that orders by a user created IMMUTABLE stored procedure is consistently slower than the other three variants.Wow, interesting.I'm surprised we never realized this before, but
here's the deal: the generated plan computes the ORDER BY expressionseven if we end up not needing them because the ordering is created byan indexscan rather than an explicit sort step.(Such a sort step would
of course need the values as input.)So the differential you're seeingrepresents the time for all those useless evaluations of the function.The difference in the estimated cost comes from that too --- the code
doing the estimation can see perfectly well that there's an extrafunction call in the plan ...Not sure whether there's a simple way to fix this; it might take somenontrivial rejiggering in the planner.Or maybe not, but I don't have
any cute ideas about it at the moment.I wonder whether there are any other cases where we are doing uselesscomputations of resjunk columns?regards, tom lane---(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
-- Gene Hartcell: 443-604-2679


Re: [PERFORM] Setting nice values

2006-11-05 Thread Jim Nasby

On Nov 2, 2006, at 9:14 AM, Madison Kelly wrote:

  I've got a script (perl, in case it matters) that I need to run once
a month to prepare statements. This script queries and updates the
database a *lot*. I am not concerned with the performance of the SQL
calls so much as I am about the impact it has on the server's load.

  Is there a way to limit queries speed (ie: set a low 'nice' value on
a query)? This might be an odd question, or I could be asking the
question the wrong way, but hopefully you the idea. :)


The BizGres folks have been working on resource queuing, which will  
eventually do what you want. Take a look at the BizGres mailing list  
archives for more info.

--
Jim Nasby[EMAIL PROTECTED]
EnterpriseDB  http://enterprisedb.com  512.569.9461 (cell)



---(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