postgres optimized balance query

This commit is contained in:
Lex Berezhny 2020-10-21 16:48:40 -04:00
parent 4d8cc494e1
commit 6764d52634
3 changed files with 19 additions and 5 deletions

View file

@ -8,6 +8,7 @@ from ..query_context import context
from ..tables import ( from ..tables import (
SCHEMA_VERSION, metadata, Version, SCHEMA_VERSION, metadata, Version,
Claim, Support, Block, BlockFilter, BlockGroupFilter, TX, TXFilter, Claim, Support, Block, BlockFilter, BlockGroupFilter, TX, TXFilter,
pg_add_account_address_constraints_and_indexes
) )
@ -105,6 +106,8 @@ def check_version_and_create_tables():
ctx.execute(Version.insert().values(version=SCHEMA_VERSION)) ctx.execute(Version.insert().values(version=SCHEMA_VERSION))
for table in metadata.sorted_tables: for table in metadata.sorted_tables:
disable_trigger_and_constraints(table.name) disable_trigger_and_constraints(table.name)
if ctx.is_postgres:
ctx.execute(text(pg_add_account_address_constraints_and_indexes))
def disable_trigger_and_constraints(table_name): def disable_trigger_and_constraints(table_name):

View file

@ -535,7 +535,14 @@ def get_txo_sum(**constraints):
def get_balance(account_ids): def get_balance(account_ids):
ctx = context()
my_addresses = select(AccountAddress.c.address).where(in_account_ids(account_ids)) my_addresses = select(AccountAddress.c.address).where(in_account_ids(account_ids))
if ctx.is_postgres:
txo_address_check = TXO.c.address == func.any(func.array(my_addresses))
txi_address_check = TXI.c.address == func.any(func.array(my_addresses))
else:
txo_address_check = TXO.c.address.in_(my_addresses)
txi_address_check = TXI.c.address.in_(my_addresses)
query = ( query = (
select( select(
func.sum(TXO.c.amount).label("total"), func.sum(TXO.c.amount).label("total"),
@ -553,18 +560,17 @@ def get_balance(account_ids):
)).label("supports"), )).label("supports"),
func.sum(case( func.sum(case(
[(where_txo_type_in(TXO_TYPES["support"]) & ( [(where_txo_type_in(TXO_TYPES["support"]) & (
(TXI.c.address.isnot(None)) & (TXI.c.address.isnot(None)) & txi_address_check
(TXI.c.address.in_(my_addresses))
), TXO.c.amount)], ), TXO.c.amount)],
else_=0 else_=0
)).label("my_supports"), )).label("my_supports"),
) )
.where((TXO.c.spent_height == 0) & (TXO.c.address.in_(my_addresses))) .where((TXO.c.spent_height == 0) & txo_address_check)
.select_from( .select_from(
TXO.join(TXI, (TXI.c.position == 0) & (TXI.c.tx_hash == TXO.c.tx_hash), isouter=True) TXO.join(TXI, (TXI.c.position == 0) & (TXI.c.tx_hash == TXO.c.tx_hash), isouter=True)
) )
) )
result = context().fetchone(query) result = ctx.fetchone(query)
return { return {
"total": result["total"], "total": result["total"],
"available": result["total"] - result["reserved"], "available": result["total"] - result["reserved"],

View file

@ -45,6 +45,11 @@ AccountAddress = Table(
) )
pg_add_account_address_constraints_and_indexes = [
"CREATE UNIQUE INDEX account_address_idx ON account_address (account, address);"
]
Block = Table( Block = Table(
'block', metadata, 'block', metadata,
Column('height', Integer, primary_key=True), Column('height', Integer, primary_key=True),
@ -160,7 +165,7 @@ pg_add_txo_constraints_and_indexes = [
f"CREATE INDEX txo_unspent_supports ON txo (claim_hash) INCLUDE (amount) " f"CREATE INDEX txo_unspent_supports ON txo (claim_hash) INCLUDE (amount) "
f"WHERE spent_height = 0 AND txo_type={TXO_TYPES['support']};", f"WHERE spent_height = 0 AND txo_type={TXO_TYPES['support']};",
# for calculating balance # for calculating balance
f"CREATE INDEX txo_unspent_by_address ON txo (address) INCLUDE (amount) " f"CREATE INDEX txo_unspent_by_address ON txo (address) INCLUDE (amount, txo_type, tx_hash) "
f"WHERE spent_height = 0;", f"WHERE spent_height = 0;",
# for finding modified claims in a block range # for finding modified claims in a block range
f"CREATE INDEX txo_claim_changes " f"CREATE INDEX txo_claim_changes "