Hi, this is a mail that I once sent to a few people at Nokia who wanted
direct access to SQL too:


> Hi guys,
> 
> I made a very simple test case that selects a LIMIT of 1 until 100 of
> a few columns out of the Services table.
> 
> After I finished the "over DBus" version of it, and while I was
> measuring its performance, I was already confident that as konttori
> pointed out too, that the DBus overhead truly is minimal when compared
> to query time.
> 
> I could write the same test with direct access and it would most
> likely shave of another few tenths of milliseconds. But for a UI
> application I don't really see the point in that (a mainloop iteration
> that has to do a few exposes and draws is likely going to take
> longer).
> 
> So I attached a vala app for testing this and I included the generated
> C source code for it. `pkg-config dbus-glib-1 --cflags --libs` it and
> for the Vala stuff take a look here:
> http://live.gnome.org/Vala/DBusSample
> 
> So this is over DBus:
> 
>         [EMAIL PROTECTED]:~/test$ ./test-sql-tracker 
>         
>         ...
>        
>         0.035126 seconds elapsed
>         [EMAIL PROTECTED]:~/test$
> 
> 
> Now with relation to the queuing: 
> 
> SQLite has a write-lock per transaction and it keeps all tables in the
> connection involved in the transaction, locked. A write lock means
> that while we (Tracker) are writing, you (your process, your
> connection, your *direct* connection to the SQLite tables indeed) is
> locked out.
> 
> Tracker writes in long transactions because SQLite is 50 or 60 times
> faster at writing if you group lots of writes together. If you don't
> do this you also have the fsync() problem more often. This is a
> similar problem as what Firefox started having when it switched to
> SQLite for several things.
> 
> Short: This means that we can't turn off our use of transactions. It's
> vital in Tracker's design and performance.
> 
> For preempting these transactions we require a very strict
> communication between the indexer and the front end query mechanism.
> This implies a synchronous DBus message to the indexer. This DBus
> message will instruct the indexer to do a preemptive commit of its
> standing transaction.
> 
> This is possible because the transaction is not done for atomicity but
> is only done for improving the write speed of SQLite (so we can early
> commit it, and we do that).
> 
> So even if we'd make a library that has a direct (in process with the
> app linking with that library) connection to the SQLite database, then
> we'd still, just like what trackerd (the front end query mechanism)
> has to do too, would need to execute a DBus message to request a
> preemptive commit to the indexer. Making it pointless to do a direct
> connection in the first place (because you still have the DBus
> overhead for this one message, anyway).
> 
> 
> Some pointers:
> 
> http://www.sqlite.org/faq.html#q5
> http://www.sqlite.org/lang_transaction.html
> 
> 
> What would be possible to avoid queuing, in case a lot of applications
> concurrently want to query Tracker, is to introduce a connection pool
> and a queue for each connection in the pool, to Tracker's query front
> end.
> 
> I must warn that although very much possible, that this solution adds
> complexity. If it's not proved that concurrent access will very often
> occur, I don't think that it's worthwhile right now to implement this
> solution already.
> 
> But we can keep it in mind for when the day comes.
> 
> /EO my advise ;)






On Tue, 2008-10-21 at 08:47 -0400, Jamie McCracken wrote:
> On Tue, 2008-10-21 at 09:36 +0100, Martyn Russell wrote:
> 
> > 
> > > Also in the future i want to support direct access to sqlite via  a
> > > client lib so we can bypass dbus (and trackerd) for select queries where
> > > speed is paramount and volume of data is too big for dbus to handle
> > > optimally (think get all my 100,000 music tracks with metadata). So this
> > > library would have to handle all querying and any future ones (like
> > > sparql) - so you will have no problem from me for implementing that
> > > support in a lib
> > 
> > Hmm, I would like to see the difference it makes using DBus and if it
> > really is an issue. We have an API like this in DBus now which Phillip
> > added - I really don't like the idea of people executing random SQL on
> > the databases. It can lead to much bigger problems. Phillip stresses
> > this in the .xml file where we document this API. I think quite rightly
> > so too.  
> 
> that should be moved to a direct access lib
> 
> the advantage of a direcdt access lib is that it removes dbus overhead
> when large amounts of data are required.
> 
> Rob taylor probably knows this better but from what i understand dbus is
> not optimal for large payloads (~1mb+) and somehting like get all music
> and metadata might involve a million plus strings which dbus would have
> to marshall, strdup and validate individually into multiple packets
> (IIRC packet size is 4kb?) so you are looking at massive overhead with
> multiple ipc calls
> 
> 
> 
> _______________________________________________
> tracker-list mailing list
> tracker-list@gnome.org
> http://mail.gnome.org/mailman/listinfo/tracker-list
> 
-- 
Philip Van Hoof, freelance software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://pvanhoof.be/blog
http://codeminded.be
using GLib;
using DBus;

public class DBusSample : GLib.Object {

    private DBus.Connection conn;
    private dynamic DBus.Object search;

    public void setup () throws DBus.Error, GLib.Error {

        // remove the space before SESSION, it is only required for this wiki
        conn = DBus.Bus.get (DBus.BusType. SESSION);

        search = conn.get_object ("org.freedesktop.Tracker", 
		"/org/freedesktop/Tracker/Search", 
		"org.freedesktop.Tracker.Search");

    }

    public void run () throws DBus.Error, GLib.Error {
		string[][] result;
		uint i = 0;

		result = search.SqlQuery ("SELECT Path, Name, Size, Rank FROM 'file-meta'.Services LIMIT 1,100");

		while (i < result.length) {
			weak string[] row = result[i];
			foreach (weak string cell in row) {
				print (cell + " ");
			}
			print ("\n");
			i++;
		}
    }

    static int main (string[] args) {
        var loop = new MainLoop (null, false);

        var test = new DBusSample ();
        try {
	    Timer timer = new Timer();
	
            test.setup ();

	    timer.start ();

            test.run ();

            print ("%f seconds elapsed\n",
               timer.elapsed ());

     //       loop.quit();
        } catch (DBus.Error e) {
            stderr.printf ("Failed to initialise: "+ e.message);
            return 1;
        } catch {
            stderr.printf ("Dynamic method failure");
            return 1;
        }

   //     loop.run ();

        return 0;
    }
}
_______________________________________________
tracker-list mailing list
tracker-list@gnome.org
http://mail.gnome.org/mailman/listinfo/tracker-list

Reply via email to