These indexes weren't helping in practice, so remove them. Avoid some queries during a full refresh to load in maybe 1/3rd the time.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3800 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2022-01-29 19:00:44 +00:00
parent d77c452120
commit 0ddb86b5a8
3 changed files with 70 additions and 53 deletions

View File

@ -1 +1 @@
{"type":"tildefriends-app","files":{"app.js":"&ZPex8H1nwzrEHSgi5SkvfTlSzSIutT6iHOY08LWkwZg=.sha256","index.html":"&H2L4kR9xDS6oS7EDpesDCDB3JXDjcLTBg9XoR2mZaZw=.sha256","vue-material.js":"&K5cdLqXYCENPak/TCINHQhyJhpS4G9DlZHGwoh/LF2g=.sha256","tf-user.js":"&DdJwZYEo7AqFyutYMvEjykoVXxdHVog0UXye6Sbo0TU=.sha256","tf-message.js":"&3dPiSNYjoJE3zn1oTT1SBhbvkW9MHr7ZUDxUJiBI1Ss=.sha256","tf.js":"&RAwMitnSkY+F3lDbyXAvWYT1QOX0lUsNZC+JE7KW4JM=.sha256","commonmark.min.js":"&EP0OeR9zyLwZannz+0ga4s9AGES2RLvvIIQYHqqV6+k=.sha256","vue.js":"&g1wvA+yHl1sVC+eufTsg9If7ZeVyMTBU+h0tks7ZNzE=.sha256","vue-material-theme-default-dark.css":"&RP2nr+2CR18BpHHw5ST9a5GJUCOG9n0G2kuGkcQioWE=.sha256","vue-material.min.css":"&kGbUM2QgFSyHZRzqQb0b+0S3EVIlZ0AXpdiAVjIhou8=.sha256","roboto.css":"&jJv43Om673mQO5JK0jj7714s5E+5Yrf82H6LcDx7wUs=.sha256","material-icons.css":"&a28PdcVvgq/DxyIvJAx/e+ZOEtOuHnr3kjLWKyzH11M=.sha256","tf-shared.js":"&+qPP3g4CAUlkt8K4iBCZ+F5Fy6N7fu6MggvSVss2juE=.sha256"}} {"type":"tildefriends-app","files":{"app.js":"&OOcUHSIAA6CR2dYSv2BwOMBZ1hjFg+PJZPABhZMe1Gc=.sha256","index.html":"&H2L4kR9xDS6oS7EDpesDCDB3JXDjcLTBg9XoR2mZaZw=.sha256","vue-material.js":"&K5cdLqXYCENPak/TCINHQhyJhpS4G9DlZHGwoh/LF2g=.sha256","tf-user.js":"&DdJwZYEo7AqFyutYMvEjykoVXxdHVog0UXye6Sbo0TU=.sha256","tf-message.js":"&3dPiSNYjoJE3zn1oTT1SBhbvkW9MHr7ZUDxUJiBI1Ss=.sha256","tf.js":"&RAwMitnSkY+F3lDbyXAvWYT1QOX0lUsNZC+JE7KW4JM=.sha256","commonmark.min.js":"&EP0OeR9zyLwZannz+0ga4s9AGES2RLvvIIQYHqqV6+k=.sha256","vue.js":"&g1wvA+yHl1sVC+eufTsg9If7ZeVyMTBU+h0tks7ZNzE=.sha256","vue-material-theme-default-dark.css":"&RP2nr+2CR18BpHHw5ST9a5GJUCOG9n0G2kuGkcQioWE=.sha256","vue-material.min.css":"&kGbUM2QgFSyHZRzqQb0b+0S3EVIlZ0AXpdiAVjIhou8=.sha256","roboto.css":"&jJv43Om673mQO5JK0jj7714s5E+5Yrf82H6LcDx7wUs=.sha256","material-icons.css":"&a28PdcVvgq/DxyIvJAx/e+ZOEtOuHnr3kjLWKyzH11M=.sha256","tf-shared.js":"&+qPP3g4CAUlkt8K4iBCZ+F5Fy6N7fu6MggvSVss2juE=.sha256"}}

View File

@ -7,8 +7,9 @@ var g_ready = false;
var g_selected = null; var g_selected = null;
var g_following_cache = {}; var g_following_cache = {};
var g_followers_cache = {};
var g_following_deep_cache = {}; var g_following_deep_cache = {};
var g_stats = {};
var g_sequence = {};
async function following(db, id) { async function following(db, id) {
if (g_following_cache[id]) { if (g_following_cache[id]) {
@ -41,6 +42,7 @@ async function following(db, id) {
f.users.delete(row.contact); f.users.delete(row.contact);
} }
f.sequence = row.sequence; f.sequence = row.sequence;
g_sequence[id] = row.sequence;
}); });
var as_set = f.users; var as_set = f.users;
f.users = Array.from(f.users).sort(); f.users = Array.from(f.users).sort();
@ -76,34 +78,38 @@ async function getAbout(db, id) {
if (!f || f.version != k_version) { if (!f || f.version != k_version) {
f = {about: {}, sequence: 0, version: k_version}; f = {about: {}, sequence: 0, version: k_version};
} }
await ssb.sqlStream( if (g_sequence[id] > f.sequence) {
"SELECT "+ await ssb.sqlStream(
" sequence, "+ "SELECT "+
" content "+ " sequence, "+
"FROM messages "+ " content "+
"WHERE "+ "FROM messages "+
" sequence > ?1 AND "+ "WHERE "+
" author = ?2 AND "+ " author = ?1 AND "+
" json_extract(content, '$.type') = 'about' AND "+ " sequence > ?2 AND "+
" json_extract(content, '$.about') = author "+ " json_extract(content, '$.type') = 'about' AND "+
"UNION SELECT MAX(sequence) as sequence, NULL FROM messages WHERE author = ?2 "+ " json_extract(content, '$.about') = ?1 "+
"ORDER BY sequence", "UNION SELECT MAX(sequence) as sequence, NULL FROM messages WHERE author = ?1 "+
[f.sequence, id], "ORDER BY sequence",
function(row) { [id, f.sequence],
f.sequence = row.sequence; function(row) {
if (row.content) { g_stats.rows_read = (g_stats.rows_read || 0) + 1;
var about = {}; f.sequence = row.sequence;
try { if (row.content) {
about = JSON.parse(row.content); var about = {};
} catch { try {
about = JSON.parse(row.content);
} catch {
}
delete about.about;
delete about.type;
f.about = Object.assign(f.about, about);
} }
delete about.about; });
delete about.type; }
f.about = Object.assign(f.about, about);
}
});
var j = JSON.stringify(f); var j = JSON.stringify(f);
if (o != j) { if (o != j) {
g_stats.rows_written = (g_stats.rows_written || 0) + 1;
await db.set(id + ":about", j); await db.set(id + ":about", j);
} }
return f.about; return f.about;
@ -250,27 +256,29 @@ async function getVotes(db, id) {
if (!f || f.version != k_version) { if (!f || f.version != k_version) {
f = {votes: [], sequence: 0, version: k_version}; f = {votes: [], sequence: 0, version: k_version};
} }
await ssb.sqlStream( if (g_sequence[id] > f.sequence) {
"SELECT "+ await ssb.sqlStream(
" author, "+ "SELECT "+
" id, "+ " author, "+
" sequence, "+ " id, "+
" timestamp, "+ " sequence, "+
" content "+ " timestamp, "+
"FROM messages "+ " content "+
"WHERE "+ "FROM messages "+
" author = ? AND "+ "WHERE "+
" sequence > ? AND "+ " author = ? AND "+
" json_extract(content, '$.type') = 'vote' "+ " sequence > ? AND "+
"UNION SELECT NULL, NULL, MAX(sequence), NULL, NULL FROM messages WHERE author = ? "+ " json_extract(content, '$.type') = 'vote' "+
"ORDER BY sequence DESC LIMIT ?", "UNION SELECT NULL, NULL, MAX(sequence), NULL, NULL FROM messages WHERE author = ? "+
[f.sequence, id, id, k_votes_max], "ORDER BY sequence DESC LIMIT ?",
function(row) { [f.sequence, id, id, k_votes_max],
if (row.id) { function(row) {
votes.push(row); if (row.id) {
} votes.push(row);
f.sequence = Math.max(f.sequence, row.sequence); }
}); f.sequence = Math.max(f.sequence, row.sequence);
});
}
f.votes = [].concat(votes, f.votes).slice(0, k_votes_max); f.votes = [].concat(votes, f.votes).slice(0, k_votes_max);
var j = JSON.stringify(f); var j = JSON.stringify(f);
if (o != j) { if (o != j) {
@ -308,8 +316,8 @@ async function refresh(selected) {
var timing = []; var timing = [];
timing.push({name: 'start', time: new Date()}); timing.push({name: 'start', time: new Date()});
g_following_cache = {}; g_following_cache = {};
g_followers_cache = {};
g_following_deep_cache = {}; g_following_deep_cache = {};
g_sequence = {};
await app.postMessage({clear: true}); await app.postMessage({clear: true});
var whoami = await ssb.whoami(); var whoami = await ssb.whoami();
var db = await database("ssb"); var db = await database("ssb");
@ -353,13 +361,24 @@ async function refresh(selected) {
timing.push({name: 'get_root_posts', time: new Date()}); timing.push({name: 'get_root_posts', time: new Date()});
await Promise.all(all_posts.map(x => app.postMessage({message: x}))); await Promise.all(all_posts.map(x => app.postMessage({message: x})));
timing.push({name: 'send_posts', time: new Date()}); timing.push({name: 'send_posts', time: new Date()});
await Promise.all(all_followed.map(id => getAbout(db, id).then(results => app.postMessage({user: {user: id, about: results}})))); await Promise.all(all_followed.map(id => getAbout(db, id).then(results => Object.keys(results).length ? app.postMessage({user: {user: id, about: results}}) : null)));
timing.push({name: 'about', time: new Date()}); timing.push({name: 'about', time: new Date()});
await Promise.all(all_followed.map(id => getVotes(db, id).then(results => results.length ? app.postMessage({votes: results}) : null))); await Promise.all(all_followed.map(id => getVotes(db, id).then(results => results.length ? app.postMessage({votes: results}) : null)));
timing.push({name: 'votes', time: new Date()}); timing.push({name: 'votes', time: new Date()});
await Promise.all(all_followed.map(id => following(db, id).then(results => app.postMessage({following: {id: id, users: [...results]}})))); await all_followed.map(
id => app.postMessage(
{
following: {
id: id,
users: [...(g_following_cache[id] || [])],
}
}
)
);
timing.push({name: 'following', time: new Date()}); timing.push({name: 'following', time: new Date()});
print(JSON.stringify(g_stats));
var times = {}; var times = {};
var previous = null; var previous = null;
for (let t of timing) { for (let t of timing) {

View File

@ -30,8 +30,6 @@ void tf_ssb_db_init(tf_ssb_t* ssb)
sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_id_index ON messages (author, id)", NULL, NULL, NULL); sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_id_index ON messages (author, id)", NULL, NULL, NULL);
sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_sequence_index ON messages (author, sequence)", NULL, NULL, NULL); sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_sequence_index ON messages (author, sequence)", NULL, NULL, NULL);
sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_timestamp_index ON messages (author, timestamp)", NULL, NULL, NULL); sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_timestamp_index ON messages (author, timestamp)", NULL, NULL, NULL);
sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_type_sequence_index ON messages (author, json_extract(content, '$.type'), sequence)", NULL, NULL, NULL);
sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_type_timestamp_index ON messages (author, json_extract(content, '$.type'), timestamp)", NULL, NULL, NULL);
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS blobs (" "CREATE TABLE IF NOT EXISTS blobs ("
" id TEXT PRIMARY KEY," " id TEXT PRIMARY KEY,"