-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Binary field very very very slow. Why ?
PostPosted: Wed Oct 05, 2005 7:02 am 
I'm writing an application which store files in a SQL Server database.
I use the binary (or BinaryBlob) tag on the hbm.xml and Byte[] on the .cs.
All is good if the files are very small ( < 100 kbytes) but when I try to store a 3MBytes in the database, this takes 10-15 seconds.

Is it normal ? How can I improve this ?

Thanks in advance.


Top
  
 
 Post subject:
PostPosted: Wed Oct 05, 2005 8:26 am 
Contributor
Contributor

Joined: Thu May 12, 2005 9:45 am
Posts: 593
Location: nhibernate.org
Do you know where is the bottleneck? I am not sure it is in NHibernate...

You may try to build a test doing the same thing with DataSet/DataReader.

_________________
Pierre Henri Kuaté.
Get NHibernate in Action Now!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 05, 2005 9:03 am 
Regular
Regular

Joined: Fri Jun 11, 2004 6:27 am
Posts: 81
Location: Yaroslavl, Russia
Only a quick suppostion: this could be related to the size of data chunks used by ADO.NET to update BLOB fields. Try to dig in that direction.

_________________
Best,
Andrew Mayorov // BYTE-force


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 05, 2005 9:04 am 
Ok, I will do a DataSet example to compare and will come back with the result.


Top
  
 
 Post subject:
PostPosted: Wed Oct 05, 2005 1:10 pm 
I did a example with 2 forms (1 for DataSet and 1 for NHibernate) which populate a DataGrid with a list of document.
For the example, I add only one document of 3 Mbytes.

1) With the DataSet Form, it takes 1 second to show the form.
2) With the NHibernate Form, it takes 17 seconds to show the form.

ps : the 2 forms use a Usercontrol to show the data. The only difference is the way the data are loaded.

I can't understand this. What must I do ? Where must I search ?


Top
  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 2:59 am 
Regular
Regular

Joined: Fri Jun 11, 2004 6:27 am
Posts: 81
Location: Yaroslavl, Russia
I think the problem is in the NHibernate.Type.BinaryType.Get method. It reads from binary fields using 2Kb-long buffer. Try to increase the buffer length (currently it must be done in the source code, there is no such config parameter).

_________________
Best,
Andrew Mayorov // BYTE-force


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 3:32 am 
I just download the latest release (RC3) and the time is now of 4 seconds for the same operation so I really think it was a matter of the 0.910 beta version.

So thanks to NHibernate team.


Top
  
 
 Post subject: Last but not least, thanks to xor
PostPosted: Thu Oct 06, 2005 3:49 am 
Yes xor, I increase the BinaryType buffer length and it resolves the matter completely. I think the NHibernate team should do something to take this to consideration for the next releases.

Thanks to you.


Top
  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 7:00 am 
Contributor
Contributor

Joined: Thu May 12, 2005 9:45 am
Posts: 593
Location: nhibernate.org
I think that we should add a parameter to define the default buffer length...
The nicest solution would be to put it in the mapping so that it can be customized for each case.

Can you create a Jira issue?
http://jira.nhibernate.org

_________________
Pierre Henri Kuaté.
Get NHibernate in Action Now!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 7:55 am 
When I inspect the BinaryType.Get method, I saw some comments which surprised me let me think that this method isn't really finished.
Let see by yourself.
Code:
public override object Get( IDataReader rs, int index )
{
    if( Environment.UseStreamsForBinary )
    {
        // Is this really necessary?
        // see http://msdn.microsoft.com/library/en-us/cpguide/html/cpconobtainingblobvaluesfromdatabase.asp?frame=true
        // for a how to on reading binary/blob values from a db...
        MemoryStream outputStream = new MemoryStream( 2048 );
        byte[ ] buffer = new byte[2048];
        long fieldOffset = 0;

        try
        {
            while( true )
            {
                long amountRead = rs.GetBytes( index, fieldOffset, buffer, 0, buffer.Length );
                fieldOffset += amountRead;
                outputStream.Write( buffer, 0, ( int ) amountRead );

                if( amountRead < buffer.Length )
                {
                   break;
                }
            }
            outputStream.Close();
        }
        catch( IOException ioe )
        {
            throw new HibernateException( "IOException occurred reading a binary value", ioe );
        }

        return outputStream.ToArray();
    }
    else
    {
        //TODO: not sure if this will work with all dbs
        return ( byte[ ] ) rs[ index ];
    }
}

Is this really necessary ?
At this time, the else part is never executed because Environment.UseStreamsForBinary return always true.
So I think this need to be explored deeply because if the else part work with all dbs, this is the solution.


Top
  
 
 Post subject:
PostPosted: Fri Nov 18, 2005 1:07 pm 
Senior
Senior

Joined: Sat Sep 10, 2005 3:46 pm
Posts: 178
I see that this was fixed in the latest release. Is there an actual configuration property to control the buffer size?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.