Subject Re: [Firebird-Java] Re: Blob Performance hints?
Author Rick Fincher
The problem turned out to be using an unbuffered stream with getBytes.
Instead of: in = rs.getBinaryStream("BINARYFILE");

If I use:
BufferedInputStream bis = new BufferedInputStream(
rs.getBinaryStream("BINARYFILE") );

The performance improves by a factor of 4 to 5. The other slow downs I
forgot to mention in earlier posts are that the web app is running on a
secure server so the response is encrypted, and the database is a 64 bit I/O
version of Firebird.

By using the buffered input stream I got about 1 meg per second (as opposed
to 0.2 meg per second). Considering the encryption, that is reasonably
close to Roman's 2-2.5 megabyte per second. That is about the same as I got
using getBytes to grab the whole document into a byte array in memory before
transmitting. I don't know what the speed penalty of using 64 bit I/O on a
32 bit processor is, but I imagine there is some.

Buffering the output stream made no difference, I presume this is because
ServletOutputStream is already buffered.

Changing the default size of the buffer seemed to make no difference either.

A point of interest: Displaying a 10 megabyte pdf file in an Internet
Explorer browser on Win 2000, the file stored as a blob in a Firebird 64 bit
database served from a secure Tomcat servlet engine on a Linux server took
about 3 times as long as displaying it with Apache from a disk file,
unencrypted. The client and server were on separate machines, Tomcat,
JayBird, and Firebird were on the same server.

I think most of that is the result of the encryption. In past web apps I've
done encryption in Tomcat just about doubled the delay.

So using Tomcat, JayBird, Firebird compares favorably, taking about 1.5
times as long to display files, with the added benefits of the sql search
capability and the integrity of having the files in the database where they
can be managed much more easily.

There is also a significant time lag the first time a pdf is displayed while
the browser loads the Acrobat pdf display plug-in, so be careful to run
speed tests after the first pdf is displayed.

Thanks for all the help.


----- Original Message -----
> Roman replied:
> > Are you using subType 0 (bin) or 1 (text)? I initially created the
> > blob field as subType 0, will this cause problems with rs.getString?
> Currently you have good chances of getting your data with
> str.getBytes() back only if client's encoding is NONE and no
> manipulation with string is performed. In this case string still keeps
> all data even some bytes are not defined in the default JVM character
> set. I do not know if this behaviour stays forever.
> > > Check if ResultSet.getBytes(int) works faster (only as a test).
> >
> > I was getting about 0.2 meg per second. After I tried this it
> > increased to about 1.0 meg per sec.
> >
> > I think the rest of the difference can be attributed to the overhead
> > of the servlet engine, etc.
> Can you measure the database performance by reading data with
> ResultSet.getBinaryStream(int) and sending them to /dev/null? Maybe
> this is the servlet container/network that does not like 1k blocks in
> response?
> > Why did you say to use only use ResultSet.getBytes(int) as a test?
> > Is there a problem with using it?
> Do you have so much memory in your servlet container than you happily
> can keep 10x20Mb byte arrays in RAM? ResultSet.getBytes(int) fetches
> all data at once and keeps it in memory. This will work for one user,
> but it is not scalable.
> Best regards,
> Roman