Skip to content

Commit aed69e6

Browse files
rustyrussellmadelinevibes
authored andcommitted
sql: only create sql indices after initial load of data.
This makes a big difference for large tables. Consider 1.6M channelmoves, which took 82 seconds to populate, now takes 17 seconds: Before: plugin-sql: Time to call listchannelmoves: 10.380341485 seconds plugin-sql: Time to refresh channelmoves: 82.311287310 seconds After: plugin-sql: Time to call listchannelmoves: 9.962815480 seconds plugin-sql: Time to refresh channelmoves: 15.711549299 seconds plugin-sql: Time to refresh + create indices for channelmoves: 17.100151235 seconds tests/test_coinmoves.py::test_generate_coinmoves (50,000): Time (from start to end of l2 node): 27 seconds Worst latency: 16.0 seconds Changelog-Changed: Plugins: `sql` initial load for tables is much faster (e.g 82 to 17 seconds for very large channelmoves table). Signed-off-by: Rusty Russell <[email protected]>
1 parent d996522 commit aed69e6

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

plugins/sql.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ struct table_desc {
122122
bool is_subobject;
123123
/* Do we use created_index as primary key? Otherwise we create rowid. */
124124
bool has_created_index;
125+
/* Have we created our sql indexes yet? */
126+
bool indices_created;
125127
/* function to refresh it. */
126128
struct command_result *(*refresh)(struct command *cmd,
127129
const struct table_desc *td,
@@ -490,6 +492,28 @@ static struct command_result *refresh_complete(struct command *cmd,
490492
return command_finished(cmd, ret);
491493
}
492494

495+
static void init_indices(struct plugin *plugin, const struct table_desc *td)
496+
{
497+
for (size_t i = 0; i < ARRAY_SIZE(indices); i++) {
498+
char *errmsg, *cmd;
499+
int err;
500+
501+
if (!streq(indices[i].tablename, td->name))
502+
continue;
503+
504+
cmd = tal_fmt(tmpctx, "CREATE INDEX %s_%zu_idx ON %s (%s",
505+
indices[i].tablename, i,
506+
indices[i].tablename,
507+
indices[i].fields[0]);
508+
if (indices[i].fields[1])
509+
tal_append_fmt(&cmd, ", %s", indices[i].fields[1]);
510+
tal_append_fmt(&cmd, ");");
511+
err = sqlite3_exec(db, cmd, NULL, NULL, &errmsg);
512+
if (err != SQLITE_OK)
513+
plugin_err(plugin, "Failed '%s': %s", cmd, errmsg);
514+
}
515+
}
516+
493517
/* Recursion */
494518
static struct command_result *refresh_tables(struct command *cmd,
495519
struct db_query *dbq);
@@ -505,6 +529,11 @@ static struct command_result *one_refresh_done(struct command *cmd,
505529
assert(td->refreshing);
506530
td->refreshing = false;
507531

532+
if (!td->indices_created) {
533+
init_indices(cmd->plugin, td);
534+
td->indices_created = 1;
535+
}
536+
508537
/* Transfer refresh waiters onto local list */
509538
list_head_init(&waiters);
510539
list_append_list(&waiters, &td->refresh_waiters);
@@ -1527,6 +1556,7 @@ static struct table_desc *new_table_desc(const tal_t *ctx,
15271556
td->last_created_index = 0;
15281557
td->has_created_index = false;
15291558
td->refreshing = false;
1559+
td->indices_created = false;
15301560
list_head_init(&td->refresh_waiters);
15311561

15321562
/* Only top-levels have refresh functions */
@@ -1707,25 +1737,6 @@ static void init_tablemap(struct plugin *plugin)
17071737
}
17081738
}
17091739

1710-
static void init_indices(struct plugin *plugin)
1711-
{
1712-
for (size_t i = 0; i < ARRAY_SIZE(indices); i++) {
1713-
char *errmsg, *cmd;
1714-
int err;
1715-
1716-
cmd = tal_fmt(tmpctx, "CREATE INDEX %s_%zu_idx ON %s (%s",
1717-
indices[i].tablename, i,
1718-
indices[i].tablename,
1719-
indices[i].fields[0]);
1720-
if (indices[i].fields[1])
1721-
tal_append_fmt(&cmd, ", %s", indices[i].fields[1]);
1722-
tal_append_fmt(&cmd, ");");
1723-
err = sqlite3_exec(db, cmd, NULL, NULL, &errmsg);
1724-
if (err != SQLITE_OK)
1725-
plugin_err(plugin, "Failed '%s': %s", cmd, errmsg);
1726-
}
1727-
}
1728-
17291740
static void memleak_mark_tablemap(struct plugin *p, struct htable *memtable)
17301741
{
17311742
memleak_ptr(memtable, dbfilename);
@@ -1738,7 +1749,6 @@ static const char *init(struct command *init_cmd,
17381749
struct plugin *plugin = init_cmd->plugin;
17391750
db = sqlite_setup(plugin);
17401751
init_tablemap(plugin);
1741-
init_indices(plugin);
17421752

17431753
plugin_set_memleak_handler(plugin, memleak_mark_tablemap);
17441754
return NULL;

0 commit comments

Comments
 (0)