Bug 699597 - Autocomplete using GAL is slow
authorDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 20 May 2013 13:14:24 +0000 (14:14 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 20 May 2013 13:14:24 +0000 (14:14 +0100)
With large addressbooks, using an inner join which produces hundreds of
thousands of duplicate results, and then filtering them back down to what
we really wanted with 'DISTINCT' is really inefficient. I can't even tell
you *how* inefficient, because it didn't complete a single query in the
hours that I left it running. Switch it to a more sensible outer join and
it completes in a second or so on my 216000-entry address book.

addressbook/libedata-book/e-book-backend-sqlitedb.c

index e355db6..374cd86 100644 (file)
@@ -3412,7 +3412,7 @@ convert_match_exp (struct _ESExp *f,
                                if (is_list) {
                                        gchar *tmp;
 
-                                       tmp = sqlite3_mprintf ("summary.uid = multi.uid AND multi.field = %Q", field);
+                                       tmp = sqlite3_mprintf ("multi.field = %Q", field);
                                        str = g_strdup_printf (
                                                "(%s AND (%s %s %s%s))",
                                                tmp, field_name, oper, query_term,
@@ -3629,7 +3629,8 @@ book_backend_sqlitedb_search_query (EBookBackendSqliteDB *ebsdb,
                                gchar *list_table = g_strconcat (folderid, "_lists", NULL);
 
                                stmt = sqlite3_mprintf (
-                                       "%s FROM %Q AS summary, %Q AS multi WHERE %s",
+                                       "%s FROM %Q AS summary "
+                                       "LEFT OUTER JOIN %Q AS multi ON summary.uid = multi.uid WHERE %s",
                                        select_portion, folderid, list_table, sql);
                                g_free (list_table);
                        } else {
@@ -3662,8 +3663,8 @@ book_backend_sqlitedb_search_query (EBookBackendSqliteDB *ebsdb,
                                gchar *list_table = g_strconcat (folderid, "_lists", NULL);
 
                                stmt = sqlite3_mprintf (
-                                       "SELECT DISTINCT summary.uid, vcard, bdata "
-                                       "FROM %Q AS summary, %Q AS multi WHERE %s",
+                                       "SELECT DISTINCT summary.uid, vcard, bdata FROM %Q AS summary "
+                                       "LEFT OUTER JOIN %Q AS multi ON summary.uid = multi.uid WHERE %s",
                                        folderid, list_table, sql);
                                g_free (list_table);
                        } else {
@@ -3911,7 +3912,8 @@ e_book_backend_sqlitedb_search_uids (EBookBackendSqliteDB *ebsdb,
                                gchar *list_table = g_strconcat (folderid, "_lists", NULL);
 
                                stmt = sqlite3_mprintf (
-                                       "SELECT DISTINCT summary.uid FROM %Q AS summary, %Q AS multi WHERE %s",
+                                       "SELECT DISTINCT summary.uid FROM %Q AS summary "
+                                       "LEFT OUTER JOIN %Q AS multi ON summary.uid = multi.uid WHERE %s",
                                        folderid, list_table, sql_query);
 
                                g_free (list_table);