On Oct 14, 2010, at 5:43 PM, Jens Miltner wrote:

> I just stumbled across a problem where sqlite would be stuck for  
> quite a long time inside sqlite3VdbeExpandSql when using bound BLOB  
> parameters, i.e. my query looks like
>
> INSERT INTO foo VALUES (?,?,?,?...)
>
> and one of the parameters is a BLOB of about 700k.
>
> What I found is that when this query is executed, SQLite will  
> actually produce a string representation of the BLOB, which is done  
> using the following loop:
>
>>     assert( pVar->flags & MEM_Blob );
>>     sqlite3StrAccumAppend(&out, "x'", 2);
>>     for(i=0; i<pVar->n; i++){
>>       sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
>>     }
>>     sqlite3StrAccumAppend(&out, "'", 1);
>
> Here, sqlite3XPrintf will call sqlite3StrAcuumAppend, which  
> essentially mallocs a new block that is 3 bytes larger than the old  
> block, copies the old data, appends 2 characters (hex digits) and  
> frees the old block.
>
> This looks like it would be *very* inefficient. I haven't noticed  
> this problem before, so I'm not sure there are other conditions that  
> cause this code path to be used now, but I thought I'd raise the  
> question nonetheless to clear this issue.
>
> (I'm using SQLite 3.6.22 on Mac OS X).
>
> Any ideas / answers?

It only does that if you have an sqlite3_trace() hook registered.

If it's a problem, maybe you can clear the hook (by passing NULL
to sqlite3_trace()) temporarily while executing queries that use
large blobs. Or don't use it at all, if you can live without SQL
tracing.

Dan.

_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to