[python-sybase] Re: FW: Is Python Sybase module slow compared to Perl DBI?

Dave Cole djc at object-craft.com.au
24 Sep 2002 01:32:09 +1000


chuck> Oops...accidentially hit the send button.  For a single table:
chuck> 
chuck> time (secs)  type/settings
chuck> -----------  ---------------------------------------------------
chuck>         160  Perl DBI
chuck>         320  sybase-0.34
chuck>         340  sybase-0.35pre2, fetchone
chuck>         265  sybase-0.35pre2, fetchone, locking=0
chuck>         153  sybase-0.35pre2, fetchmany, arraysize=32
chuck>         151  sybase-0.35pre2, fetchmany, arraysize=32, locking=0
chuck>         150  sybase-0.35pre2, fetchmany, arraysize=64
chuck>         150  sybase-0.35pre2, fetchmany, arraysize=64, locking=0
chuck>         155  sybase-0.35pre2, fetchmany, arraysize=128
chuck>         153  sybase-0.35pre2, fetchmany, arraysize=128, locking=0
chuck> 
chuck> The wierd thing also it that the locking doesn't seem to affect
chuck> the run once I started using the fetchmany.  Here is the new
chuck> source code I used:
chuck> 
chuck>         db = Sybase.connect(server, user, password, database) #, locking
chuck> = 0)
chuck> 
chuck>         # output the actual data
chuck>         c = db.cursor()
chuck>         c.arraysize = 64
chuck>         c.execute("SELECT %s FROM %s" % (select, table))
chuck>     
chuck>         num_recs = 0
chuck>         if os.path.isfile("%s.gz" % dumpfile):
chuck>             os.remove("%s.gz" % dumpfile)
chuck>         file = os.popen("gzip -c > %s.gz" % dumpfile, "w")
chuck>         while 1:
chuck>             rows = c.fetchmany()
chuck>             if not rows : break
chuck>     
chuck>             for row in rows:
chuck>                 line = []
chuck>                 for i in range(len(row)):
chuck>                     line.append("%-*s" % (lengths[i], row[i]))
chuck>                 print >> file, "".join(line)
chuck>                 num_recs += 1
chuck> 
chuck>         file.close()
chuck>         c.close()
chuck> 
chuck> What is the locking doing?  It is internal Python thread
chuck> locking, or is it Sybase locking?

The locking allows you to share database connections between Python
threads.  It is implemented in the Sybase.py code - by turning it off
you disable all of the associated function calls to the standard
Python threading module.

If you look closer at Sybase.py and read the sybasect documentation
you will see that the low level module also implements locking for
multiple threaded programs.  This is disabled in Sybase.py by the call
_ctx.ct_con_alloc(0) (the 0 turns off locking).  In sybasect I have
implemented (I think) all of the documented rules for multi-threaded
access to the Sybase CT library.  Since the connection level locks in
Sybase.py are much more coarse I turn off the fine grained locking in
the low level module.  The low level module can be used in a
standalone fashion - Sybase.py is just one example of how you can use
sybasect.so.

The reason for the locking in Sybase.py is that a database connection
is implemented (in Sybase) via a TCP socket which talks the TDS
(Tabular Data Stream (I think)) protocol.  TDS only supports a single
result set at a time over the socket - this represents a "small"
problem when you might want to have multiple cursors in your
multi-threaded program using the same connection...

So, what the Sybase.py locking code does is place a lock on the
connection when you do a Cursor.execute() or Cursor.callproc() then
releases the lock once the results have either been fetched or
cancelled.  This makes the single result set limitation mostly
invisible to your Python code.

If you are not using threads in your application you may as well pass
locking = 0 to the Sybase.connect() function.

chuck> Thanks again for the help.  I'd say that Python and Perl are
chuck> effectively now running at the same speed!

That is absolutely awesome!!!  I have made some more slight changes
which sped my test program up by another 10%.  I a version of the
changes I made to the python-sybase mailing list (minus the further
10% speedup):

     http://object-craft.com.au/cgi-bin/mailman/listinfo/python-sybase

If I do not get any reports of problems in the next week I am going to
make a new release.  Mind you I still have not had any report of
success as yet (excluding yours of course)...

Thank you very much for helping out.

- Dave

-- 
http://www.object-craft.com.au