Re: [GENERAL] timer script from SAMS book or equivalent?

2007-10-11 Thread John Wells
The version sent yesterday was creating a LOT of unnecessary objects when 
running queries with large result sets. I tweaked the postpres-pr classes (via 
Ruby's very nice open class mechanism). The updated version is below...it took 
queries running 10+ minutes down to around 20 seconds.

Thanks,
John

-
require 'rubygems'
require 'postgres-pr/connection'
require 'postgres-pr/message'


$tupleQuery = SELECT relname, seq_scan, 
  seq_tup_read, idx_scan, 
  idx_tup_fetch 
   FROM pg_stat_all_tables


$blockQuery = SELECT relname, heap_blks_read, 
  heap_blks_hit, idx_blks_read, 
  idx_blks_hit 
   FROM pg_statio_all_tables

$use_jdbc = false

def usage
  app = File.basename $0
  usstr = -EOL
#{app} query [tablename] 
  or 
#{app} /path/to/file/containing/query.sql [tablename]
  
Example: #{app} select * from users users

Note: the following environment variables MUST be set:
PG_TIMER_DB   - name of the database
PG_TIMER_USER - name of database user
PG_TIMER_PASS - password of database user
PG_TIMER_URI  - connection uri that postgres-pr understands.
  Examples:
tcp://localhost:5432
unix:/tmp/.s.PGSQL.5432
  EOL
  puts usstr  
  exit
end

class PostgresPR::Connection::Result
  def get_field_at_row(field, row)  
idx = @fields.collect{|f|f.name}.index field
@rows[row][idx]
  end
end

class PostgresPR::Connection
  def query_no_results(sql)
puts Running query in background. Waiting...
@conn  PostgresPR::Query.dump(sql)
loop do  
  msg = PostgresPR::Message.read_without_buffer(@conn)
  case msg  
  when PostgresPR::ReadyForQuery
break  
  end
end
  end
end

class PostgresPR::Message
  def self.read_without_buffer(stream, startup=false)
type = stream.readbytes(1).unpack('C').first unless startup
length = stream.readbytes(4).unpack('N').first  # FIXME: length should be 
signed, not unsigned
if type==?Z
  buffer = Buffer.of_size(startup ? length : 1+length)
  buffer.write_byte(type) unless startup
  buffer.write_int32_network(length)
  buffer.copy_from_stream(stream, length-4)
  (startup ? StartupMessage : MsgTypeMap[type]).create(buffer)
else 
  stream.read(length - 4)
  return nil
end
  end
end

class PureDBUtil  
def initialize()
 
@conn = PostgresPR::Connection.new($dbname, 
   $dbuser, 
   $dbpass, 
   $dburi)  
end
  def start_tran 
@conn.query(BEGIN)
end
def commit(results=true)
if results
  @conn.query(COMMIT) 
else
  @conn.query_no_results(COMMIT)
end
end
def exec(query, results=true) 
if results 
  @conn.query(query) 
else
  @conn.query_no_results(query)
end
end
end

class JDBCDBUtil
def initialize(dbname=nil)
raise Exception, not implemented
end  
end

def getTupleValues(tran, table_name=nil)
if table_name.nil?
return tran.exec($tupleQuery +  ORDER by relname)
else
return tran.exec($tupleQuery +  WHERE relname = 
'#{table_name}' )
end
end

def getBlockValues(tran, table_name)
if table_name.nil?
return tran.exec($blockQuery +  ORDER by relname)
else
return tran.exec($blockQuery +  WHERE relname = 
'#{table_name}' )
end
end

def getDelta(n, beginning, ending, col)
  endVal = 0
  begVal = 0 
  endVal = ending.get_field_at_row(col, n)
  begVal = beginning.get_field_at_row(col, n)
  return endVal.to_f - begVal.to_f;
end


def gcw(res, col)
max = 0
0.upto res.rows.size-1 do |n|
fld_size = res.get_field_at_row(col, n).size
if fld_size  max
max = fld_size
end
end
return max
end

def fill(len, c)
c * len
end


def printDeltas(begTuples, endTuples, begBlocks, endBlocks)
nameWidth = gcw(begTuples, relname)
  str = 
  str  '+'  fill( nameWidth, '-' )  
+---+--+  
\n;
  str  '|'  fill( nameWidth, ' ' )  | SEQUENTIAL I/O
|INDEXED I/O   |  \n;
  str  '|'  fill( nameWidth, ' ' )  | scans | tuples |heap_blks  
|cached| scans | tuples | idx_blks |cached|  \n;
  str  '|'  fill( nameWidth, '-' )  
+---++---+--+---++--+--+  
\n;
  totSeqScans  = 0
  totSeqTuples = 0
  totHeapBlks  = 0
  totHeapHits  = 0
  totIdxScans  = 0
  totIdxTuples = 0
  totIdxBlks   = 0
  totIdxHits   = 0
  tableCount   = 0

  0.upto begTuples.rows.size-1 do |row|   

Re: [GENERAL] timer script from SAMS book or equivalent?

2007-10-10 Thread John Wells
Could someone explain to me how the connection is initialized below? I'm 
re-writing the script in Ruby...but this is a stumbling block for me in the way 
the C++ libs work. Does the library initial conn automagically? How would one 
emulate this in another language...would it be to run it as the postgres user 
and connection to template1?

Thanks,
John

int main( int argc, char * argv[] )
{
   // how is this being initialized?
   connection conn;

   work tran1( conn, getBegValues );

   const result  begTupleValues = getTupleValues( tran1, argc  2 ?
argv[2] : 0 );
   const result  begBlockValues = getBlockValues( tran1, argc  2 ?
argv[2] : 0 );

   const result  ignore = tran1.exec( argv[1] );

   tran1.commit();

   sleep( 1 );

   work tran2( conn, getEndValues );

   const result  endTupleValues = getTupleValues( tran2, argc  2 ?
argv[2] : 0 );
   const result  endBlockValues = getBlockValues( tran2, argc  2 ?
argv[2] : 0 );

   printDeltas( begTupleValues, endTupleValues, begBlockValues,
endBlockValues );

   
} 

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

   http://archives.postgresql.org/


Re: [GENERAL] timer script from SAMS book or equivalent?

2007-10-10 Thread John Wells
My Ruby version is found below. Note it requires the postgres-pr ruby driver. 
Also note I didn't really ruby-ize it to much...for the most part it's a 
one-to-one translation. 

One different thing to note...this script expects you to have postgres-pr 
installed via rubygems. You can modify the require statements (actually just 
comment out the rubygems line) if you're is installed in a non-rubygems way.

Also note, this requires you to define your connection parameters in env 
variables, which works in my situation.

PG_TIMER_DB   - name of the database
PG_TIMER_USER - name of database user
PG_TIMER_PASS - password of database user
PG_TIMER_URI  - connection uri that postgres-pr understands.
  Examples:
tcp://localhost:5432
unix:/tmp/.s.PGSQL.5432


Hope it helps someone else.

###
require 'rubygems'
require 'postgres-pr/connection'


$tupleQuery = SELECT relname, seq_scan, 
  seq_tup_read, idx_scan, 
  idx_tup_fetch 
   FROM pg_stat_all_tables


$blockQuery = SELECT relname, heap_blks_read, 
  heap_blks_hit, idx_blks_read, 
  idx_blks_hit 
   FROM pg_statio_all_tables

$use_jdbc = false

def usage
  usstr = -EOL
#{$0} query
Example: #{$0} select * from users

Note: the following environment variables MUST be set:
PG_TIMER_DB   - name of the database
PG_TIMER_USER - name of database user
PG_TIMER_PASS - password of database user
PG_TIMER_URI  - connection uri that postgres-pr understands.
  Examples:
tcp://localhost:5432
unix:/tmp/.s.PGSQL.5432
  EOL
  puts usstr
  exit()
end

$dbname = ENV['PG_TIMER_DB']
$dbuser = ENV['PG_TIMER_USER']
$dbpass = ENV['PG_TIMER_PASS']
$dburi  = ENV['PG_TIMER_URI']

[$dbname, $dbuser, $dbpass, $dburi].each do |one|
  one.nil?  usage()
end

class PostgresPR::Connection::Result
  def get_field_at_row(field, row)  
idx = @fields.collect{|f|f.name}.index field
@rows[row][idx]
  end
end


class PureDBUtil  
def initialize()
  @conn = PostgresPR::Connection.new($dbname, 
   $dbuser, 
   $dbpass, 
   $dburi)  
end
  def start_tran 
@conn.query(BEGIN)
end
def commit
@conn.query(COMMIT)
end
def exec(query)  
@conn.query(query)
end
end

class JDBCDBUtil
def initialize(dbname=nil)
raise Exception, not implemented
end  
end

def getTupleValues(tran, table_name=nil)
if !table_name.nil?
return tran.exec($tupleQuery +  ORDER by relname)
else
return tran.exec($tupleQuery +  WHERE relname = 
'#{table_name}' )
end
end

def getBlockValues(tran, table_name)
if !table_name.nil?
return tran.exec($blockQuery +  ORDER by relname)
else
return tran.exec($blockQuery +  WHERE relname = 
'#{table_name}' )
end
end

def getDelta(n, beginning, ending, col)
  endVal = 0
  begVal = 0 
  endVal = ending.get_field_at_row(col, n)
  begVal = beginning.get_field_at_row(col, n)
  return endVal.to_f - begVal.to_f;
end


def getColumnWidth(res, col)
max = 0
res.rows.each do |one|
if one[col].size  max
max = one[col].size
end
end
return max
end

def fill(len, c)
c * len
end


def printDeltas(begTuples, endTuples, begBlocks, endBlocks)
nameWidth = 15
  str = 
  str  '+'  fill( nameWidth, '-' )  
+---+--+  
\n;
  str  '|'  fill( nameWidth, ' ' )  | SEQUENTIAL I/O
|INDEXED I/O   |  \n;
  str  '|'  fill( nameWidth, ' ' )  | scans | tuples |heap_blks |cached 
| scans | tuples | idx_blks |cached|  \n;
  str  '|'  fill( nameWidth, '-' )  
+---++---+--+---++--+--+  
\n;
  totSeqScans  = 0
  totSeqTuples = 0
  totHeapBlks  = 0
  totHeapHits  = 0
  totIdxScans  = 0
  totIdxTuples = 0
  totIdxBlks   = 0
  totIdxHits   = 0
  tableCount   = 0

  0.upto begTuples.rows.size-1 do |row|
seqScans  = getDelta(row, begTuples, endTuples, seq_scan)
seqTuples = getDelta(row, begTuples, endTuples, seq_tup_read)
heapBlks  = getDelta(row, begBlocks, endBlocks, heap_blks_read)
heapHits  = getDelta(row, begBlocks, endBlocks, heap_blks_hit)
idxScans  = getDelta(row, begTuples, endTuples, idx_scan)
idxTuples = getDelta(row, begTuples, endTuples, idx_tup_fetch)
idxBlks   = getDelta(row, begBlocks, endBlocks, idx_blks_read)
idxHits   = getDelta(row, begBlocks, endBlocks, idx_blks_hit)  

if(( seqScans + seqTuples + heapBlks + 
 heapHits + idxScans + idxTuples + 
 

Re: [GENERAL] timer script from SAMS book or equivalent?

2007-10-10 Thread John Wells
Sorry...the first version was a bit rash and left out some 
features...particularly filtering by table. Here's the patch to correct:

If anyone wants the corrected version, email me off list.

Thanks,
John


# diff -w pg_timer_old.rb pg_timer.rb
18a19
   app = File.basename $0
20,21c21,25
 #{$0} query
 Example: #{$0} select * from users
---
 #{app} query [tablename]
   or
 #{app} /path/to/file/containing/query.sql [tablename]

 Example: #{app} select * from users users
54a59

78c83
 if !table_name.nil?
---
   if table_name.nil?
86c91
 if !table_name.nil?
---
   if table_name.nil?
194c199,211
   arg = args[0]
---
   first = args[0]
   query = nil
   if !first.nil? and File.exists?(first)
 File.open(first, r) do |f|
   query = f.read
 end
   else
 query = first
   end

   table = args[1]

   usage() if args.size  1
196d212
   usage() if arg.nil?
201a218

204,206c221,223
   begTupleValues = getTupleValues(tran1, arg)
   begBlockValues = getBlockValues(tran1, arg)
   ignore = tran1.exec(args[0])
---
   begTupleValues = getTupleValues(tran1, table)
   begBlockValues = getBlockValues(tran1, table)
   ignore = tran1.exec(query)
212,213c229,232
   endTupleValues = getTupleValues(tran2, arg)
   endBlockValues = getBlockValues(tran2, arg)
---
   tran2.start_tran()
   endTupleValues = getTupleValues(tran2, table)
   endBlockValues = getBlockValues(tran2, table)
   tran2.commit()


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


Re: [GENERAL] timer script from SAMS book or equivalent?

2007-10-09 Thread John Wells
- Owen Hartnett [EMAIL PROTECTED] wrote:
 At 11:57 PM +0400 10/5/07, John Wells wrote:
 - Felipe de Jesús Molina Bravo [EMAIL PROTECTED]
 wrote:
   May be can help you \timing in psql
 
   El vie, 05-10-2007 a las 21:32 +0400, John Wells escribió:
Guys,
   
In the book PostgreSQL (2nd ed) the author mentions a timer
 script
   he wrote to analyze various performance bits about PostgreSQL.
 I've
   looked everywhere and can't find it. Does anyone know where I can
 find
   a copy, or find an equivalent tool?
 
 I'm afraid it's not even close in functionality. Here is sample 
 results from the timer tool he mentions. This is the kind of data 
 I'm after:
 
 
 This was available on line at www.developers-library.com, but now it 
 looks like that has gone away.  Sometimes an author keeps a web site 
 for code he uses to supplement a book, but I can't find one for him. 
 Here's the code:

Thanks to all. Having problems building it myself. I plan to reimplement in 
ruby if possible. Will post results.

Thanks,
John

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


Re: [GENERAL] timer script from SAMS book or equivalent?

2007-10-09 Thread korry.douglas



In the book PostgreSQL (2nd ed) the author mentions a timer script he wrote to 
analyze various performance bits about PostgreSQL. I've looked everywhere and 
can't find it. Does anyone know where I can find a copy, or find an equivalent 
tool?
  

Hi John, sorry for the delay in getting back to you.

You can find the timer program at 
http://www.conjectrix.com/pgbook/index.html.  You want the sample 
data/code for chapter 4.


  -- Korry

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


[GENERAL] timer script from SAMS book or equivalent?

2007-10-05 Thread John Wells
Guys,

In the book PostgreSQL (2nd ed) the author mentions a timer script he wrote to 
analyze various performance bits about PostgreSQL. I've looked everywhere and 
can't find it. Does anyone know where I can find a copy, or find an equivalent 
tool?

Thanks!
John

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

   http://archives.postgresql.org/


Re: [GENERAL] timer script from SAMS book or equivalent?

2007-10-05 Thread Felipe de Jesús Molina Bravo
May be can help you \timing in psql



El vie, 05-10-2007 a las 21:32 +0400, John Wells escribió:
 Guys,
 
 In the book PostgreSQL (2nd ed) the author mentions a timer script he wrote 
 to analyze various performance bits about PostgreSQL. I've looked everywhere 
 and can't find it. Does anyone know where I can find a copy, or find an 
 equivalent tool?
 
 Thanks!
 John
 
 ---(end of broadcast)---
 TIP 4: Have you searched our list archives?
 
http://archives.postgresql.org/

---(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: [GENERAL] timer script from SAMS book or equivalent?

2007-10-05 Thread John Wells

- Felipe de Jesús Molina Bravo [EMAIL PROTECTED] wrote:
 May be can help you \timing in psql
 
 El vie, 05-10-2007 a las 21:32 +0400, John Wells escribió:
  Guys,
  
  In the book PostgreSQL (2nd ed) the author mentions a timer script
 he wrote to analyze various performance bits about PostgreSQL. I've
 looked everywhere and can't find it. Does anyone know where I can find
 a copy, or find an equivalent tool?


I'm afraid it's not even close in functionality. Here is sample results from 
the timer tool he mentions. This is the kind of data I'm after:

$ timer SELECT * FROM recalls

+-++---+
| | SEQUENTIAL I/O |INDEXED I/O|
| |scans |tuples |heap_blks |cached|scans |tuples |idx_blks |cached|
|-+--+---+--+--+--+---+-+--+
|pg_aggregate |0 | 0 |1 |0 |1 | 1 |   2 |0 |
|pg_am|1 | 1 |1 |0 |0 | 0 |   0 |0 |
|pg_amop  |0 | 0 |2 |   10 |   10 |24 |   4 |   16 |
|pg_amproc|0 | 0 |1 |5 |6 | 6 |   2 |   10 |
|pg_attribute |0 | 0 |8 |   14 |   21 |65 |   6 |   57 |
|pg_cast  |0 | 0 |2 |6 |   60 | 8 |   2 |  118 |
|pg_class |4 |   740 |5 |   32 |   18 |17 |   7 |   34 |
|pg_database  |1 | 1 |1 |0 |0 | 0 |   0 |0 |
|pg_index |2 |   146 |3 |   11 |8 |12 |   4 |   12 |
|pg_namespace |2 |10 |1 |2 |2 | 1 |   2 |2 |
|pg_opclass   |0 | 0 |2 |   11 |5 |73 |   4 |6 |
|pg_operator  |0 | 0 |4 |6 |   10 |10 |   4 |   26 |
|pg_proc  |0 | 0 |6 |8 |   14 |14 |  12 |   31 |
|pg_rewrite   |0 | 0 |1 |1 |2 | 2 |   2 |2 |
|pg_shadow|0 | 0 |1 |2 |3 | 3 |   4 |2 |
|pg_statistic |0 | 0 |3 |5 |   33 | 8 |   2 |   64 |
|pg_trigger   |0 | 0 |1 |1 |2 | 2 |   2 |2 |
|pg_type  |0 | 0 |2 |5 |7 | 7 |   2 |   12 |
|recalls  |1 | 39241 | 4413 |0 |0 | 0 |   0 |0 |
+-+--+---+--+--+--+---+-+--+
|Totals   |   11 | 40139 | 4458 |  119 |  202 |   253 |  61 |  394 |
+-+--+---+--+--+--+---+-+--+


Thanks,
John

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

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