Skip to content

Commit 6bc2db5

Browse files
committed
graph, store: Load estimates for the block range distribution in tables
1 parent 34b3fca commit 6bc2db5

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

graph/src/components/store/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,11 @@ pub struct VersionStats {
928928
pub ratio: f64,
929929
/// The last block to which this table was pruned
930930
pub last_pruned_block: Option<BlockNumber>,
931+
/// The lower and upper bounds of the block ranges in this table, empty
932+
/// if the table hasn't been analyzed or if the table doesn't have a
933+
/// block_range column
934+
pub block_range_lower: Vec<BlockNumber>,
935+
pub block_range_upper: Vec<BlockNumber>,
931936
}
932937

933938
/// What phase of pruning we are working on

store/postgres/src/catalog.rs

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ use std::time::Duration;
1919
use graph::prelude::anyhow::anyhow;
2020
use graph::{
2121
data::subgraph::schema::POI_TABLE,
22-
prelude::{lazy_static, StoreError},
22+
prelude::{lazy_static, StoreError, BLOCK_NUMBER_MAX},
2323
};
2424

2525
use crate::{
26+
block_range::BLOCK_RANGE_COLUMN,
2627
pool::ForeignServer,
2728
primary::{Namespace, Site, NAMESPACE_PUBLIC},
2829
relational::SqlName,
@@ -788,10 +789,42 @@ pub fn stats(conn: &mut PgConnection, site: &Site) -> Result<Vec<VersionStats>,
788789
tablename: s.tablename,
789790
ratio: s.ratio,
790791
last_pruned_block: s.last_pruned_block,
792+
block_range_lower: vec![],
793+
block_range_upper: vec![],
791794
}
792795
}
793796
}
794797

798+
#[derive(Queryable, QueryableByName)]
799+
struct RangeHistogram {
800+
#[diesel(sql_type = Text)]
801+
tablename: String,
802+
#[diesel(sql_type = Array<Integer>)]
803+
lower: Vec<i32>,
804+
#[diesel(sql_type = Array<Integer>)]
805+
upper: Vec<i32>,
806+
}
807+
808+
fn block_range_histogram(
809+
conn: &mut PgConnection,
810+
namespace: &Namespace,
811+
) -> Result<Vec<RangeHistogram>, StoreError> {
812+
let query = format!(
813+
"select tablename, \
814+
array_agg(lower(block_range)) lower, \
815+
array_agg(coalesce(upper(block_range), {BLOCK_NUMBER_MAX})) upper \
816+
from (select tablename,
817+
unnest(range_bounds_histogram::text::int4range[]) block_range
818+
from pg_stats where schemaname = $1 and attname = '{BLOCK_RANGE_COLUMN}') a
819+
group by tablename
820+
order by tablename"
821+
);
822+
let result = sql_query(query)
823+
.bind::<Text, _>(namespace.as_str())
824+
.get_results::<RangeHistogram>(conn)?;
825+
Ok(result)
826+
}
827+
795828
// Get an estimate of number of rows (pg_class.reltuples) and number of
796829
// distinct entities (based on the planners idea of how many distinct
797830
// values there are in the `id` column) See the [Postgres
@@ -825,7 +858,27 @@ pub fn stats(conn: &mut PgConnection, site: &Site) -> Result<Vec<VersionStats>,
825858
.load::<DbStats>(conn)
826859
.map_err(StoreError::from)?;
827860

828-
Ok(stats.into_iter().map(|s| s.into()).collect())
861+
let mut range_histogram = block_range_histogram(conn, &site.namespace)?;
862+
863+
let stats = stats
864+
.into_iter()
865+
.map(|s| {
866+
// Find the range histogram for this table
867+
let pos = range_histogram
868+
.iter()
869+
.position(|h| h.tablename == s.tablename);
870+
let (lower, upper) = pos
871+
.map(|pos| range_histogram.swap_remove(pos))
872+
.map(|h| (h.lower, h.upper))
873+
.unwrap_or((vec![], vec![]));
874+
let mut vs = VersionStats::from(s);
875+
vs.block_range_lower = lower;
876+
vs.block_range_upper = upper;
877+
vs
878+
})
879+
.collect::<Vec<_>>();
880+
881+
Ok(stats)
829882
}
830883

831884
/// Return by how much the slowest replica connected to the database `conn`

store/test-store/tests/postgres/graft.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,8 @@ fn prune() {
648648
tablename: USER.to_ascii_lowercase(),
649649
ratio: 3.0 / 5.0,
650650
last_pruned_block: None,
651+
block_range_lower: vec![],
652+
block_range_upper: vec![],
651653
};
652654
assert_eq!(
653655
Some(strategy),

0 commit comments

Comments
 (0)