Skip to content

Commit fc2fb7c

Browse files
committed
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 1dda0c0 commit fc2fb7c

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
@@ -119,6 +119,8 @@ struct table_desc {
119119
bool is_subobject;
120120
/* Do we use created_index as primary key? Otherwise we create rowid. */
121121
bool has_created_index;
122+
/* Have we created our sql indexes yet? */
123+
bool indices_created;
122124
/* function to refresh it. */
123125
struct command_result *(*refresh)(struct command *cmd,
124126
const struct table_desc *td,
@@ -487,6 +489,28 @@ static struct command_result *refresh_complete(struct command *cmd,
487489
return command_finished(cmd, ret);
488490
}
489491

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

529+
if (!td->indices_created) {
530+
init_indices(cmd->plugin, td);
531+
td->indices_created = 1;
532+
}
533+
505534
/* Transfer refresh waiters onto local list */
506535
list_head_init(&waiters);
507536
list_append_list(&waiters, &td->refresh_waiters);
@@ -1524,6 +1553,7 @@ static struct table_desc *new_table_desc(const tal_t *ctx,
15241553
td->last_created_index = 0;
15251554
td->has_created_index = false;
15261555
td->refreshing = false;
1556+
td->indices_created = false;
15271557
list_head_init(&td->refresh_waiters);
15281558

15291559
/* Only top-levels have refresh functions */
@@ -1704,25 +1734,6 @@ static void init_tablemap(struct plugin *plugin)
17041734
}
17051735
}
17061736

1707-
static void init_indices(struct plugin *plugin)
1708-
{
1709-
for (size_t i = 0; i < ARRAY_SIZE(indices); i++) {
1710-
char *errmsg, *cmd;
1711-
int err;
1712-
1713-
cmd = tal_fmt(tmpctx, "CREATE INDEX %s_%zu_idx ON %s (%s",
1714-
indices[i].tablename, i,
1715-
indices[i].tablename,
1716-
indices[i].fields[0]);
1717-
if (indices[i].fields[1])
1718-
tal_append_fmt(&cmd, ", %s", indices[i].fields[1]);
1719-
tal_append_fmt(&cmd, ");");
1720-
err = sqlite3_exec(db, cmd, NULL, NULL, &errmsg);
1721-
if (err != SQLITE_OK)
1722-
plugin_err(plugin, "Failed '%s': %s", cmd, errmsg);
1723-
}
1724-
}
1725-
17261737
static void memleak_mark_tablemap(struct plugin *p, struct htable *memtable)
17271738
{
17281739
memleak_ptr(memtable, dbfilename);
@@ -1735,7 +1746,6 @@ static const char *init(struct command *init_cmd,
17351746
struct plugin *plugin = init_cmd->plugin;
17361747
db = sqlite_setup(plugin);
17371748
init_tablemap(plugin);
1738-
init_indices(plugin);
17391749

17401750
plugin_set_memleak_handler(plugin, memleak_mark_tablemap);
17411751
return NULL;

0 commit comments

Comments
 (0)