Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Query Performance When Filtering on Code in nbxv1_keypath_info View Under Specific Conditions #515

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Improve query performance when filtering on code in nbxv1_keypath_inf…
…o view
juanmigdr committed Mar 11, 2025
commit 88e12d532a44417e8e9084c3f3812cb0019d885d
2 changes: 1 addition & 1 deletion NBXplorer.Tests/DatabaseTests.cs
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ await Benchmark(conn,
"SELECT ts.script, ts.addr, ts.derivation, ts.keypath, ts.redeem FROM ( VALUES ('BTC', 'blah'), ('BTC', 'blah'), ('BTC', 'blah'), ('BTC', 'blah')) r (code, script), " +
" LATERAL(" +
" SELECT script, addr, descriptor_metadata->>'derivation' derivation, keypath, descriptors_scripts_metadata->>'redeem' redeem, descriptor_metadata->>'blindedAddress' blinded_addr " +
" FROM nbxv1_keypath_info ki " +
" FROM get_nbxv1_keypath_info(@code, r.script) ki " +
" WHERE ki.code=r.code AND ki.script=r.script) ts;", 50);
await Benchmark(conn, "SELECT o.tx_id, o.idx, o.value, o.script FROM (VALUES ('BTC', 'hash', 5), ('BTC', 'hash', 5), ('BTC', 'hash', 5)) r (code, tx_id, idx) JOIN outs o USING (code, tx_id, idx);", 50);
await Benchmark(conn, "SELECT blk_height, tx_id, wu.idx, value, script, nbxv1_get_keypath(d.metadata, ds.idx) AS keypath, d.metadata->>'feature' feature, mempool, input_mempool, seen_at FROM wallets_utxos wu JOIN descriptors_scripts ds USING (code, script) JOIN descriptors d USING (code, descriptor) WHERE code='BTC' AND wallet_id='WHALE' AND immature IS FALSE ", 50);
6 changes: 3 additions & 3 deletions NBXplorer/Backend/Repository.cs
Original file line number Diff line number Diff line change
@@ -402,7 +402,7 @@ ORDER BY idx
LIMIT 1 OFFSET @skip) AS r (script)
";
}
public override string GetKeyPathInfoPredicate() => "AND ki.descriptor=@descriptor";
public override string GetKeyPathInfoPredicate() => "ki.descriptor=@descriptor";
}
class ByScriptsQuery : GetKeyInformationsQuery
{
@@ -451,8 +451,8 @@ w.metadata AS wallet_metadata
descriptors_scripts_metadata->>'blindedAddress' blinded_addr,
descriptors_scripts_metadata->>'blindingKey' blindingKey,
descriptor_metadata->>'feature' feature
FROM nbxv1_keypath_info ki
WHERE ki.code=@code AND ki.script=r.script {query.GetKeyPathInfoPredicate()}
FROM get_nbxv1_keypath_info(@code, r.script) ki
WHERE {query.GetKeyPathInfoPredicate()}
) ts
JOIN wallets w USING(wallet_id)", parameters);
foreach (var r in rows)
39 changes: 39 additions & 0 deletions NBXplorer/DBScripts/025.GetKeyPathInfoFunction.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

CREATE OR REPLACE FUNCTION get_nbxv1_keypath_info(
input_code TEXT,
input_script TEXT
)
RETURNS TABLE (
code TEXT,
script TEXT,
addr TEXT,
descriptor_metadata JSONB,
keypath TEXT,
descriptors_scripts_metadata JSONB,
wallet_id TEXT,
idx BIGINT,
used BOOLEAN,
descriptor TEXT
) AS $$
BEGIN
RETURN QUERY
WITH filtered_wallets AS MATERIALIZED (
SELECT * FROM wallets_scripts WHERE wallets_scripts.code = input_code AND wallets_scripts.script = input_script
)
SELECT ws.code,
ws.script,
s.addr,
d.metadata AS descriptor_metadata,
nbxv1_get_keypath(d.metadata, ds.idx) AS keypath,
ds.metadata AS descriptors_scripts_metadata,
ws.wallet_id,
ds.idx,
ds.used,
d.descriptor
FROM ((filtered_wallets ws
JOIN scripts s ON (((s.code = ws.code) AND (s.script = ws.script))))
LEFT JOIN ((wallets_descriptors wd
JOIN descriptors_scripts ds ON (((ds.code = wd.code) AND (ds.descriptor = wd.descriptor))))
JOIN descriptors d ON (((d.code = ds.code) AND (d.descriptor = ds.descriptor)))) ON (((wd.wallet_id = ws.wallet_id) AND (wd.code = ws.code) AND (ds.script = ws.script))));
END;
$$ LANGUAGE plpgsql;
1 change: 1 addition & 0 deletions NBXplorer/DBScripts/FullSchema.sql
Original file line number Diff line number Diff line change
@@ -1391,6 +1391,7 @@ INSERT INTO nbxv1_migrations VALUES ('021.KeyPathInfoReturnsWalletId');
INSERT INTO nbxv1_migrations VALUES ('022.WalletsWalletsParentIdIndex');
INSERT INTO nbxv1_migrations VALUES ('023.KeyPathInfoReturnsIndex');
INSERT INTO nbxv1_migrations VALUES ('024.TrackedTxsReturnsFeature');
INSERT INTO nbxv1_migrations VALUES ('025.GetKeyPathInfoFunction');

ALTER TABLE ONLY nbxv1_migrations
ADD CONSTRAINT nbxv1_migrations_pkey PRIMARY KEY (script_name);
1 change: 1 addition & 0 deletions NBXplorer/NBXplorer.csproj
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
<None Remove="DBScripts\022.WalletsWalletsParentIdIndex.sql" />
<None Remove="DBScripts\023.KeyPathInfoReturnsIndex.sql" />
<None Remove="DBScripts\024.TrackedTxsReturnsFeature.sql" />
<None Remove="DBScripts\025.GetKeyPathInfoFunction.sql" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="DBScripts\*.sql" />