mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-09-01 18:53:50 +00:00
Fast history no background (#5873)
* Finishing up post and comment actions * Adding community_actions. * instance and person actions * Fixing person_actions. * Fixing down migrations * Adding person_content_combined. * Search combined. * Aggregates tables. * Dont rename old tables * Fixing some constraints. * Convert bigints to ints * Forgot a bigint. * Rest of i64 -> i32 * Adding actions id columns. * Fixing connection config. * Formatting smoosh up.sql * Use current_date instead of now * Adding history tables for liked_combined * Upping wal size * Fix clippy * Fixing clippy. * Fixing i64 * Getting rid of let mut conn * Adding the history status table. * Adding published indexes to speed up history. * Adding comment like history scanning. * Fixing schema options setup. * post_read history * person_post_aggregates / read_comments history * post_like history * Fixing conflicts. * Fixing clippy. * Use constant batch_size. * person content combined post and comment history. * Fixing id scanning. * post/comment_actions -> saved_combined history * search history * Post and comment aggregates -> post / comment history. * Uncommenting full history building. * Changing DB_BATCH_SIZE to i64 * Fixing clippy. * Fix index names. * Fixing diff check by removing indexes. * Adding the uplete ignore actions::id columns. * Fixing merge imports. * Fixing submodule update * Try trigger disabling. * Fix clippy * Remove history table, do faster bulk inserts. Smoosh first. Comments about how this fast insert is done is within smoosh comments. * Adding some timings. * Fast person content combined history * Adding search_combined * Fix person saved combined unique names * person_liked_combined * Remove-aggregates * Fixing up.sql issues * Re-building schema.rs * Fixing down migrations. * Removing history updating. * Format sql. * Move postgres logging to customPostgresql.conf * Try using postgres 16-alpine in CI * Speeding up add_report_count. * speed up inbox_combined * Speeding up remove_post_sort_type_enums * Fixing post_sort_type * Speeding up person votes * Fixing wrong conn. * Fixing broken migrations * Remove comment. * Make sure to re-index table after re-enabling indexes. * Removing id columns from actions tables. * Fixing down migrations. * Using create table as for smoosh migration * create_table as for person_content_combined. * Fixing person_content_combined uniques * create table as for search_combined * create table as for liked_combined * create table as for inbox_combined. * Fixing a few score types. * Fixing id positions.
This commit is contained in:
parent
b3e5e6c76a
commit
a5b0475436
51 changed files with 1343 additions and 948 deletions
|
@ -334,8 +334,7 @@ steps:
|
|||
|
||||
services:
|
||||
database:
|
||||
# 15-alpine image necessary because of diesel tests
|
||||
image: pgautoupgrade/pgautoupgrade:15-alpine
|
||||
image: pgautoupgrade/pgautoupgrade:16-alpine
|
||||
environment:
|
||||
POSTGRES_DB: lemmy
|
||||
POSTGRES_USER: postgres
|
||||
|
|
|
@ -180,7 +180,7 @@ pub fn is_top_mod(
|
|||
pub async fn update_read_comments(
|
||||
person_id: PersonId,
|
||||
post_id: PostId,
|
||||
read_comments: i64,
|
||||
read_comments: i32,
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<()> {
|
||||
let person_post_agg_form = PostReadCommentsForm::new(post_id, person_id, read_comments);
|
||||
|
|
|
@ -7,6 +7,6 @@ use url::Url;
|
|||
pub(crate) struct GroupFollowers {
|
||||
pub(crate) id: Url,
|
||||
pub(crate) r#type: CollectionType,
|
||||
pub(crate) total_items: i64,
|
||||
pub(crate) total_items: i32,
|
||||
pub(crate) items: Vec<()>,
|
||||
}
|
||||
|
|
|
@ -8,6 +8,6 @@ use url::Url;
|
|||
pub struct GroupOutbox {
|
||||
pub(crate) r#type: OrderedCollectionType,
|
||||
pub(crate) id: Url,
|
||||
pub(crate) total_items: i64,
|
||||
pub(crate) total_items: i32,
|
||||
pub(crate) ordered_items: Vec<AnnounceActivity>,
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ mod tests {
|
|||
test_parse_lemmy_item::<GroupFollowers>("assets/lemmy/collections/group_followers.json")?;
|
||||
let outbox =
|
||||
test_parse_lemmy_item::<GroupOutbox>("assets/lemmy/collections/group_outbox.json")?;
|
||||
assert_eq!(outbox.ordered_items.len() as i64, outbox.total_items);
|
||||
assert_eq!(outbox.ordered_items.len(), outbox.total_items as usize);
|
||||
test_parse_lemmy_item::<GroupFeatured>("assets/lemmy/collections/group_featured_posts.json")?;
|
||||
test_parse_lemmy_item::<GroupModerators>("assets/lemmy/collections/group_moderators.json")?;
|
||||
test_parse_lemmy_item::<EmptyOutbox>("assets/lemmy/collections/person_outbox.json")?;
|
||||
|
|
|
@ -284,7 +284,7 @@ impl Community {
|
|||
pub async fn update_federated_followers(
|
||||
pool: &mut DbPool<'_>,
|
||||
for_community_id: CommunityId,
|
||||
new_subscribers: i64,
|
||||
new_subscribers: i32,
|
||||
) -> LemmyResult<Self> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
diesel::update(community::table.find(for_community_id))
|
||||
|
|
|
@ -85,10 +85,10 @@ impl Instance {
|
|||
instance_id: InstanceId,
|
||||
form: InstanceForm,
|
||||
) -> LemmyResult<usize> {
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
diesel::update(instance::table.find(instance_id))
|
||||
.set(form)
|
||||
.execute(&mut conn)
|
||||
.execute(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateSite)
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ impl Post {
|
|||
.select(community::interactions_month)
|
||||
.inner_join(post::table.on(community::id.eq(post::community_id)))
|
||||
.filter(post::id.eq(post_id))
|
||||
.first::<i64>(conn)
|
||||
.first::<i32>(conn)
|
||||
.await?;
|
||||
|
||||
diesel::update(post::table.find(post_id))
|
||||
|
@ -520,13 +520,6 @@ impl PostActions {
|
|||
}
|
||||
|
||||
impl PostActions {
|
||||
pub fn build_many_read_forms(post_ids: &[PostId], person_id: PersonId) -> Vec<PostReadForm> {
|
||||
post_ids
|
||||
.iter()
|
||||
.map(|post_id| (PostReadForm::new(*post_id, person_id)))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub async fn read(
|
||||
pool: &mut DbPool<'_>,
|
||||
post_id: PostId,
|
||||
|
@ -553,6 +546,13 @@ impl PostActions {
|
|||
Self::read(pool, PostId(*post_id), PersonId(*person_id)).await
|
||||
}
|
||||
|
||||
pub fn build_many_read_forms(post_ids: &[PostId], person_id: PersonId) -> Vec<PostReadForm> {
|
||||
post_ids
|
||||
.iter()
|
||||
.map(|post_id| (PostReadForm::new(*post_id, person_id)))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub async fn update_notification_state(
|
||||
post_id: PostId,
|
||||
person_id: PersonId,
|
||||
|
|
|
@ -18,8 +18,22 @@ use serde_with::skip_serializing_none;
|
|||
#[cfg_attr(feature = "full", cursor_keys_module(name = person_content_combined_keys))]
|
||||
/// A combined table for a persons contents (posts and comments)
|
||||
pub struct PersonContentCombined {
|
||||
pub id: PersonContentCombinedId,
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub post_id: Option<PostId>,
|
||||
pub comment_id: Option<CommentId>,
|
||||
pub id: PersonContentCombinedId,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = person_content_combined))]
|
||||
pub struct PersonContentCombinedPostInsertForm {
|
||||
pub post_id: PostId,
|
||||
pub published_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = person_content_combined))]
|
||||
pub struct PersonContentCombinedCommentInsertForm {
|
||||
pub comment_id: CommentId,
|
||||
pub published_at: DateTime<Utc>,
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@ use serde_with::skip_serializing_none;
|
|||
#[cfg_attr(feature = "full", cursor_keys_module(name = person_liked_combined_keys))]
|
||||
/// A combined person_liked table.
|
||||
pub struct PersonLikedCombined {
|
||||
pub id: PersonLikedCombinedId,
|
||||
pub liked_at: DateTime<Utc>,
|
||||
pub like_score: i16,
|
||||
pub person_id: PersonId,
|
||||
pub post_id: Option<PostId>,
|
||||
pub comment_id: Option<CommentId>,
|
||||
pub id: PersonLikedCombinedId,
|
||||
}
|
||||
|
|
|
@ -18,9 +18,25 @@ use serde_with::skip_serializing_none;
|
|||
#[cfg_attr(feature = "full", cursor_keys_module(name = person_saved_combined_keys))]
|
||||
/// A combined person_saved table.
|
||||
pub struct PersonSavedCombined {
|
||||
pub id: PersonSavedCombinedId,
|
||||
pub saved_at: DateTime<Utc>,
|
||||
pub person_id: PersonId,
|
||||
pub post_id: Option<PostId>,
|
||||
pub comment_id: Option<CommentId>,
|
||||
pub id: PersonSavedCombinedId,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = person_saved_combined))]
|
||||
pub struct PersonSavedCombinedPostInsertForm {
|
||||
pub saved_at: DateTime<Utc>,
|
||||
pub person_id: PersonId,
|
||||
pub post_id: PostId,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = person_saved_combined))]
|
||||
pub struct PersonSavedCombinedCommentInsertForm {
|
||||
pub saved_at: DateTime<Utc>,
|
||||
pub person_id: PersonId,
|
||||
pub comment_id: CommentId,
|
||||
}
|
||||
|
|
|
@ -25,12 +25,44 @@ use serde_with::skip_serializing_none;
|
|||
#[cfg_attr(feature = "full", cursor_keys_module(name = search_combined_keys))]
|
||||
/// A combined table for a search (posts, comments, communities, persons)
|
||||
pub struct SearchCombined {
|
||||
pub id: SearchCombinedId,
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub score: i64,
|
||||
pub score: i32,
|
||||
pub post_id: Option<PostId>,
|
||||
pub comment_id: Option<CommentId>,
|
||||
pub community_id: Option<CommunityId>,
|
||||
pub person_id: Option<PersonId>,
|
||||
pub id: SearchCombinedId,
|
||||
pub multi_community_id: Option<MultiCommunityId>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = search_combined))]
|
||||
pub struct SearchCombinedPostInsertForm {
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub score: i32,
|
||||
pub post_id: PostId,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = search_combined))]
|
||||
pub struct SearchCombinedCommentInsertForm {
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub score: i32,
|
||||
pub comment_id: CommentId,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = search_combined))]
|
||||
pub struct SearchCombinedCommunityInsertForm {
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub score: i32,
|
||||
pub community_id: CommunityId,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = search_combined))]
|
||||
pub struct SearchCombinedPersonInsertForm {
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub score: i32,
|
||||
pub person_id: PersonId,
|
||||
}
|
||||
|
|
|
@ -49,9 +49,9 @@ pub struct Comment {
|
|||
/// Whether the comment has been distinguished(speaking officially) by a mod.
|
||||
pub distinguished: bool,
|
||||
pub language_id: LanguageId,
|
||||
pub score: i64,
|
||||
pub upvotes: i64,
|
||||
pub downvotes: i64,
|
||||
pub score: i32,
|
||||
pub upvotes: i32,
|
||||
pub downvotes: i32,
|
||||
/// The total number of children in this comment branch.
|
||||
pub child_count: i32,
|
||||
#[serde(skip)]
|
||||
|
|
|
@ -78,25 +78,25 @@ pub struct Community {
|
|||
pub description: Option<String>,
|
||||
#[serde(skip)]
|
||||
pub random_number: i16,
|
||||
pub subscribers: i64,
|
||||
pub posts: i64,
|
||||
pub comments: i64,
|
||||
pub subscribers: i32,
|
||||
pub posts: i32,
|
||||
pub comments: i32,
|
||||
/// The number of users with any activity in the last day.
|
||||
pub users_active_day: i64,
|
||||
pub users_active_day: i32,
|
||||
/// The number of users with any activity in the last week.
|
||||
pub users_active_week: i64,
|
||||
pub users_active_week: i32,
|
||||
/// The number of users with any activity in the last month.
|
||||
pub users_active_month: i64,
|
||||
pub users_active_month: i32,
|
||||
/// The number of users with any activity in the last year.
|
||||
pub users_active_half_year: i64,
|
||||
pub users_active_half_year: i32,
|
||||
#[serde(skip)]
|
||||
pub hot_rank: f64,
|
||||
pub subscribers_local: i64,
|
||||
pub subscribers_local: i32,
|
||||
pub report_count: i16,
|
||||
pub unresolved_report_count: i16,
|
||||
/// Number of any interactions over the last month.
|
||||
#[serde(skip)]
|
||||
pub interactions_month: i64,
|
||||
pub interactions_month: i32,
|
||||
pub local_removed: bool,
|
||||
}
|
||||
|
||||
|
@ -195,10 +195,10 @@ pub struct CommunityUpdateForm {
|
|||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
pub struct CommunityActions {
|
||||
#[serde(skip)]
|
||||
pub community_id: CommunityId,
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub community_id: CommunityId,
|
||||
/// When the community was followed.
|
||||
pub followed_at: Option<DateTime<Utc>>,
|
||||
/// The state of the community follow.
|
||||
|
|
|
@ -80,18 +80,18 @@ pub struct LocalSite {
|
|||
pub default_post_time_range_seconds: Option<i32>,
|
||||
/// Block NSFW content being created
|
||||
pub disallow_nsfw_content: bool,
|
||||
pub users: i64,
|
||||
pub posts: i64,
|
||||
pub comments: i64,
|
||||
pub communities: i64,
|
||||
pub users: i32,
|
||||
pub posts: i32,
|
||||
pub comments: i32,
|
||||
pub communities: i32,
|
||||
/// The number of users with any activity in the last day.
|
||||
pub users_active_day: i64,
|
||||
pub users_active_day: i32,
|
||||
/// The number of users with any activity in the last week.
|
||||
pub users_active_week: i64,
|
||||
pub users_active_week: i32,
|
||||
/// The number of users with any activity in the last month.
|
||||
pub users_active_month: i64,
|
||||
pub users_active_month: i32,
|
||||
/// The number of users with any activity in the last half year.
|
||||
pub users_active_half_year: i64,
|
||||
pub users_active_half_year: i32,
|
||||
/// Dont send email notifications to users for new replies, mentions etc
|
||||
pub disable_email_notifications: bool,
|
||||
pub suggested_communities: Option<MultiCommunityId>,
|
||||
|
|
|
@ -56,12 +56,12 @@ pub struct Person {
|
|||
/// Whether the person is a bot account.
|
||||
pub bot_account: bool,
|
||||
pub instance_id: InstanceId,
|
||||
pub post_count: i64,
|
||||
pub post_count: i32,
|
||||
#[serde(skip)]
|
||||
pub post_score: i64,
|
||||
pub comment_count: i64,
|
||||
pub post_score: i32,
|
||||
pub comment_count: i32,
|
||||
#[serde(skip)]
|
||||
pub comment_score: i64,
|
||||
pub comment_score: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone, derive_new::new)]
|
||||
|
@ -134,11 +134,11 @@ pub struct PersonUpdateForm {
|
|||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
pub struct PersonActions {
|
||||
#[serde(skip)]
|
||||
pub target_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub target_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub followed_at: Option<DateTime<Utc>>,
|
||||
#[serde(skip)]
|
||||
pub follow_pending: Option<bool>,
|
||||
|
|
|
@ -62,10 +62,10 @@ pub struct Post {
|
|||
pub alt_text: Option<String>,
|
||||
/// Time at which the post will be published. None means publish immediately.
|
||||
pub scheduled_publish_time_at: Option<DateTime<Utc>>,
|
||||
pub comments: i64,
|
||||
pub score: i64,
|
||||
pub upvotes: i64,
|
||||
pub downvotes: i64,
|
||||
pub comments: i32,
|
||||
pub score: i32,
|
||||
pub upvotes: i32,
|
||||
pub downvotes: i32,
|
||||
#[serde(skip)]
|
||||
/// A newest comment time, limited to 2 days, to prevent necrobumping
|
||||
pub newest_comment_time_necro_at: DateTime<Utc>,
|
||||
|
@ -183,17 +183,17 @@ pub struct PostUpdateForm {
|
|||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
pub struct PostActions {
|
||||
#[serde(skip)]
|
||||
pub post_id: PostId,
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub post_id: PostId,
|
||||
/// When the post was read.
|
||||
pub read_at: Option<DateTime<Utc>>,
|
||||
/// When was the last time you read the comments.
|
||||
pub read_comments_at: Option<DateTime<Utc>>,
|
||||
/// The number of comments you read last. Subtract this from total comments to get an unread
|
||||
/// count.
|
||||
pub read_comments_amount: Option<i64>,
|
||||
pub read_comments_amount: Option<i32>,
|
||||
/// When the post was saved.
|
||||
pub saved_at: Option<DateTime<Utc>>,
|
||||
/// When the post was liked.
|
||||
|
@ -245,7 +245,7 @@ pub struct PostReadForm {
|
|||
pub struct PostReadCommentsForm {
|
||||
pub post_id: PostId,
|
||||
pub person_id: PersonId,
|
||||
pub read_comments_amount: i64,
|
||||
pub read_comments_amount: i32,
|
||||
#[new(value = "Utc::now()")]
|
||||
pub read_comments_at: DateTime<Utc>,
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ use rustls::{
|
|||
};
|
||||
use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
sync::{Arc, OnceLock},
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
use tracing::error;
|
||||
|
@ -62,8 +62,6 @@ pub const SITEMAP_LIMIT: i64 = 50000;
|
|||
pub const SITEMAP_DAYS: TimeDelta = TimeDelta::days(31);
|
||||
pub const RANK_DEFAULT: f64 = 0.0001;
|
||||
|
||||
/// Some connection options to speed up queries
|
||||
const CONNECTION_OPTIONS: [&str; 1] = ["geqo_threshold=12"];
|
||||
pub type ActualDbPool = Pool<AsyncPgConnection>;
|
||||
|
||||
/// References a pool or connection. Functions must take `&mut DbPool<'_>` to allow implicit
|
||||
|
@ -370,38 +368,8 @@ pub fn diesel_url_create(opt: Option<&str>) -> LemmyResult<Option<DbUrl>> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets a few additional config options necessary for starting lemmy
|
||||
fn build_config_options_uri_segment(config: &str) -> LemmyResult<String> {
|
||||
let mut url = Url::parse(config)?;
|
||||
|
||||
// Set `lemmy.protocol_and_hostname` so triggers can use it
|
||||
let lemmy_protocol_and_hostname_option =
|
||||
"lemmy.protocol_and_hostname=".to_owned() + &SETTINGS.get_protocol_and_hostname();
|
||||
let mut options = CONNECTION_OPTIONS.to_vec();
|
||||
options.push(&lemmy_protocol_and_hostname_option);
|
||||
|
||||
// Create the connection uri portion
|
||||
let options_segments = options
|
||||
.iter()
|
||||
.map(|o| "-c ".to_owned() + o)
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ");
|
||||
|
||||
url.set_query(Some(&format!("options={options_segments}")));
|
||||
Ok(url.into())
|
||||
}
|
||||
|
||||
fn establish_connection(config: &str) -> BoxFuture<'_, ConnectionResult<AsyncPgConnection>> {
|
||||
let fut = async {
|
||||
/// Use a once_lock to create the postgres connection config, since this config never changes
|
||||
static POSTGRES_CONFIG_WITH_OPTIONS: OnceLock<String> = OnceLock::new();
|
||||
|
||||
let config = POSTGRES_CONFIG_WITH_OPTIONS.get_or_init(|| {
|
||||
build_config_options_uri_segment(config)
|
||||
.inspect_err(|e| error!("Couldn't parse postgres connection URI: {e}"))
|
||||
.unwrap_or_default()
|
||||
});
|
||||
|
||||
// We only support TLS with sslmode=require currently
|
||||
let conn = if config.contains("sslmode=require") {
|
||||
let rustls_config = DangerousClientConfigBuilder {
|
||||
|
@ -481,7 +449,7 @@ impl ServerCertVerifier for NoCertVerifier {
|
|||
}
|
||||
|
||||
pub fn build_db_pool() -> LemmyResult<ActualDbPool> {
|
||||
let db_url = SETTINGS.get_database_url();
|
||||
let db_url = SETTINGS.get_database_url_with_options()?;
|
||||
// diesel-async does not support any TLS connections out of the box, so we need to manually
|
||||
// provide a setup function which handles creating the connection
|
||||
let mut config = ManagerConfig::default();
|
||||
|
@ -515,16 +483,16 @@ pub fn build_db_pool_for_tests() -> ActualDbPool {
|
|||
}
|
||||
|
||||
pub mod functions {
|
||||
use diesel::sql_types::{BigInt, Text, Timestamptz};
|
||||
use diesel::sql_types::{Int4, Text, Timestamptz};
|
||||
|
||||
define_sql_function! {
|
||||
#[sql_name = "r.hot_rank"]
|
||||
fn hot_rank(score: BigInt, time: Timestamptz) -> Double;
|
||||
fn hot_rank(score: Int4, time: Timestamptz) -> Double;
|
||||
}
|
||||
|
||||
define_sql_function! {
|
||||
#[sql_name = "r.scaled_rank"]
|
||||
fn scaled_rank(score: BigInt, time: Timestamptz, interactions_month: BigInt) -> Double;
|
||||
fn scaled_rank(score: Int4, time: Timestamptz, interactions_month: Int4) -> Double;
|
||||
}
|
||||
|
||||
define_sql_function!(fn lower(x: Text) -> Text);
|
||||
|
|
|
@ -146,9 +146,9 @@ diesel::table! {
|
|||
path -> Ltree,
|
||||
distinguished -> Bool,
|
||||
language_id -> Int4,
|
||||
score -> Int8,
|
||||
upvotes -> Int8,
|
||||
downvotes -> Int8,
|
||||
score -> Int4,
|
||||
upvotes -> Int4,
|
||||
downvotes -> Int4,
|
||||
child_count -> Int4,
|
||||
hot_rank -> Float8,
|
||||
controversy_rank -> Float8,
|
||||
|
@ -221,18 +221,18 @@ diesel::table! {
|
|||
#[max_length = 150]
|
||||
description -> Nullable<Varchar>,
|
||||
random_number -> Int2,
|
||||
subscribers -> Int8,
|
||||
posts -> Int8,
|
||||
comments -> Int8,
|
||||
users_active_day -> Int8,
|
||||
users_active_week -> Int8,
|
||||
users_active_month -> Int8,
|
||||
users_active_half_year -> Int8,
|
||||
subscribers -> Int4,
|
||||
posts -> Int4,
|
||||
comments -> Int4,
|
||||
users_active_day -> Int4,
|
||||
users_active_week -> Int4,
|
||||
users_active_month -> Int4,
|
||||
users_active_half_year -> Int4,
|
||||
hot_rank -> Float8,
|
||||
subscribers_local -> Int8,
|
||||
subscribers_local -> Int4,
|
||||
report_count -> Int2,
|
||||
unresolved_report_count -> Int2,
|
||||
interactions_month -> Int8,
|
||||
interactions_month -> Int4,
|
||||
local_removed -> Bool,
|
||||
}
|
||||
}
|
||||
|
@ -243,8 +243,8 @@ diesel::table! {
|
|||
use super::sql_types::CommunityNotificationsModeEnum;
|
||||
|
||||
community_actions (person_id, community_id) {
|
||||
community_id -> Int4,
|
||||
person_id -> Int4,
|
||||
community_id -> Int4,
|
||||
followed_at -> Nullable<Timestamptz>,
|
||||
follow_state -> Nullable<CommunityFollowerState>,
|
||||
follow_approver_id -> Nullable<Int4>,
|
||||
|
@ -257,9 +257,10 @@ diesel::table! {
|
|||
}
|
||||
|
||||
diesel::table! {
|
||||
community_community_follow (target_id, community_id) {
|
||||
community_community_follow (community_id, target_id) {
|
||||
target_id -> Int4,
|
||||
community_id -> Int4,
|
||||
published_at -> Timestamptz,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,14 +443,14 @@ diesel::table! {
|
|||
comment_downvotes -> FederationModeEnum,
|
||||
default_post_time_range_seconds -> Nullable<Int4>,
|
||||
disallow_nsfw_content -> Bool,
|
||||
users -> Int8,
|
||||
posts -> Int8,
|
||||
comments -> Int8,
|
||||
communities -> Int8,
|
||||
users_active_day -> Int8,
|
||||
users_active_week -> Int8,
|
||||
users_active_month -> Int8,
|
||||
users_active_half_year -> Int8,
|
||||
users -> Int4,
|
||||
posts -> Int4,
|
||||
comments -> Int4,
|
||||
communities -> Int4,
|
||||
users_active_day -> Int4,
|
||||
users_active_week -> Int4,
|
||||
users_active_month -> Int4,
|
||||
users_active_half_year -> Int4,
|
||||
disable_email_notifications -> Bool,
|
||||
suggested_communities -> Nullable<Int4>,
|
||||
multi_comm_follower -> Int4,
|
||||
|
@ -832,17 +833,17 @@ diesel::table! {
|
|||
matrix_user_id -> Nullable<Text>,
|
||||
bot_account -> Bool,
|
||||
instance_id -> Int4,
|
||||
post_count -> Int8,
|
||||
post_score -> Int8,
|
||||
comment_count -> Int8,
|
||||
comment_score -> Int8,
|
||||
post_count -> Int4,
|
||||
post_score -> Int4,
|
||||
comment_count -> Int4,
|
||||
comment_score -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
person_actions (person_id, target_id) {
|
||||
target_id -> Int4,
|
||||
person_id -> Int4,
|
||||
target_id -> Int4,
|
||||
followed_at -> Nullable<Timestamptz>,
|
||||
follow_pending -> Nullable<Bool>,
|
||||
blocked_at -> Nullable<Timestamptz>,
|
||||
|
@ -856,31 +857,31 @@ diesel::table! {
|
|||
|
||||
diesel::table! {
|
||||
person_content_combined (id) {
|
||||
id -> Int4,
|
||||
published_at -> Timestamptz,
|
||||
post_id -> Nullable<Int4>,
|
||||
comment_id -> Nullable<Int4>,
|
||||
id -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
person_liked_combined (id) {
|
||||
id -> Int4,
|
||||
liked_at -> Timestamptz,
|
||||
like_score -> Int2,
|
||||
person_id -> Int4,
|
||||
post_id -> Nullable<Int4>,
|
||||
comment_id -> Nullable<Int4>,
|
||||
id -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
person_saved_combined (id) {
|
||||
id -> Int4,
|
||||
saved_at -> Timestamptz,
|
||||
person_id -> Int4,
|
||||
post_id -> Nullable<Int4>,
|
||||
comment_id -> Nullable<Int4>,
|
||||
id -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,10 +914,10 @@ diesel::table! {
|
|||
url_content_type -> Nullable<Text>,
|
||||
alt_text -> Nullable<Text>,
|
||||
scheduled_publish_time_at -> Nullable<Timestamptz>,
|
||||
comments -> Int8,
|
||||
score -> Int8,
|
||||
upvotes -> Int8,
|
||||
downvotes -> Int8,
|
||||
comments -> Int4,
|
||||
score -> Int4,
|
||||
upvotes -> Int4,
|
||||
downvotes -> Int4,
|
||||
newest_comment_time_necro_at -> Timestamptz,
|
||||
newest_comment_time_at -> Timestamptz,
|
||||
hot_rank -> Float8,
|
||||
|
@ -934,11 +935,11 @@ diesel::table! {
|
|||
use super::sql_types::PostNotificationsModeEnum;
|
||||
|
||||
post_actions (person_id, post_id) {
|
||||
post_id -> Int4,
|
||||
person_id -> Int4,
|
||||
post_id -> Int4,
|
||||
read_at -> Nullable<Timestamptz>,
|
||||
read_comments_at -> Nullable<Timestamptz>,
|
||||
read_comments_amount -> Nullable<Int8>,
|
||||
read_comments_amount -> Nullable<Int4>,
|
||||
saved_at -> Nullable<Timestamptz>,
|
||||
liked_at -> Nullable<Timestamptz>,
|
||||
like_score -> Nullable<Int2>,
|
||||
|
@ -1041,13 +1042,13 @@ diesel::table! {
|
|||
|
||||
diesel::table! {
|
||||
search_combined (id) {
|
||||
id -> Int4,
|
||||
published_at -> Timestamptz,
|
||||
score -> Int8,
|
||||
score -> Int4,
|
||||
post_id -> Nullable<Int4>,
|
||||
comment_id -> Nullable<Int4>,
|
||||
community_id -> Nullable<Int4>,
|
||||
person_id -> Nullable<Int4>,
|
||||
id -> Int4,
|
||||
multi_community_id -> Nullable<Int4>,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ pub enum Branch {
|
|||
|
||||
pub fn run(options: Options, db_url: &str) -> anyhow::Result<Branch> {
|
||||
// Migrations don't support async connection, and this function doesn't need to be async
|
||||
let mut conn = PgConnection::establish(db_url)?;
|
||||
let conn = &mut PgConnection::establish(db_url)?;
|
||||
|
||||
// If possible, skip getting a lock and recreating the "r" schema, so
|
||||
// lemmy_server processes in a horizontally scaled setup can start without causing locks
|
||||
|
@ -203,7 +203,7 @@ pub fn run(options: Options, db_url: &str) -> anyhow::Result<Branch> {
|
|||
|
||||
let schema_exists = exists(pg_namespace::table.find("r"));
|
||||
|
||||
if select(sql_unchanged.and(schema_exists)).get_result(&mut conn)? {
|
||||
if select(sql_unchanged.and(schema_exists)).get_result(conn)? {
|
||||
return Ok(Branch::EarlyReturn);
|
||||
}
|
||||
}
|
||||
|
@ -216,9 +216,9 @@ pub fn run(options: Options, db_url: &str) -> anyhow::Result<Branch> {
|
|||
|
||||
// Drop `r` schema, so migrations don't need to be made to work both with and without things in
|
||||
// it existing
|
||||
revert_replaceable_schema(&mut conn)?;
|
||||
revert_replaceable_schema(conn)?;
|
||||
|
||||
run_selected_migrations(&mut conn, &options).map_err(convert_err)?;
|
||||
run_selected_migrations(conn, &options).map_err(convert_err)?;
|
||||
|
||||
// Only run replaceable_schema if newest migration was applied
|
||||
let output = if (options.run && options.limit.is_none())
|
||||
|
@ -230,8 +230,8 @@ pub fn run(options: Options, db_url: &str) -> anyhow::Result<Branch> {
|
|||
if options.enable_diff_check {
|
||||
let before = diff_check::get_dump();
|
||||
|
||||
run_replaceable_schema(&mut conn)?;
|
||||
revert_replaceable_schema(&mut conn)?;
|
||||
run_replaceable_schema(conn)?;
|
||||
revert_replaceable_schema(conn)?;
|
||||
|
||||
let after = diff_check::get_dump();
|
||||
|
||||
|
@ -240,7 +240,7 @@ pub fn run(options: Options, db_url: &str) -> anyhow::Result<Branch> {
|
|||
diff_check::deferr_constraint_check(&after);
|
||||
}
|
||||
|
||||
run_replaceable_schema(&mut conn)?;
|
||||
run_replaceable_schema(conn)?;
|
||||
|
||||
Branch::ReplaceableSchemaRebuilt
|
||||
} else {
|
||||
|
@ -383,7 +383,7 @@ mod tests {
|
|||
fn test_schema_setup() -> LemmyResult<()> {
|
||||
let o = Options::default();
|
||||
let db_url = SETTINGS.get_database_url();
|
||||
let mut conn = PgConnection::establish(&db_url)?;
|
||||
let conn = &mut PgConnection::establish(&db_url)?;
|
||||
|
||||
// Start with consistent state by dropping everything
|
||||
conn.batch_execute("DROP OWNED BY CURRENT_USER;")?;
|
||||
|
@ -395,7 +395,7 @@ mod tests {
|
|||
);
|
||||
|
||||
// Insert the test data
|
||||
insert_test_data(&mut conn)?;
|
||||
insert_test_data(conn)?;
|
||||
|
||||
// Run all migrations, and make sure that changes can be correctly reverted
|
||||
assert_eq!(
|
||||
|
@ -404,11 +404,11 @@ mod tests {
|
|||
);
|
||||
|
||||
// Check the test data we inserted before after running migrations
|
||||
check_test_data(&mut conn)?;
|
||||
check_test_data(conn)?;
|
||||
|
||||
// Check the current schema
|
||||
assert_eq!(
|
||||
get_foreign_keys_with_missing_indexes(&mut conn)?,
|
||||
get_foreign_keys_with_missing_indexes(conn)?,
|
||||
Vec::<String>::new(),
|
||||
"each foreign key needs an index so that deleting the referenced row does not scan the whole referencing table"
|
||||
);
|
||||
|
@ -595,7 +595,7 @@ mod tests {
|
|||
assert_eq!(posts[0].4, TEST_COMMUNITY_ID_1);
|
||||
assert_eq!(posts[0].5, TEST_USER_ID_1);
|
||||
|
||||
let comments: Vec<(i32, String, String, i32, i32, Ltree, i64)> = comment::table
|
||||
let comments: Vec<(i32, String, String, i32, i32, Ltree, i32)> = comment::table
|
||||
.select((
|
||||
comment::id,
|
||||
comment::content,
|
||||
|
|
|
@ -66,13 +66,14 @@ impl CommunityFollowerView {
|
|||
pub async fn count_community_followers(
|
||||
pool: &mut DbPool<'_>,
|
||||
community_id: CommunityId,
|
||||
) -> LemmyResult<i64> {
|
||||
) -> LemmyResult<i32> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
Self::joins()
|
||||
.filter(community_actions::community_id.eq(community_id))
|
||||
.select(count_star())
|
||||
.first::<i64>(conn)
|
||||
.await
|
||||
.map(i32::try_from)?
|
||||
.with_lemmy_type(LemmyErrorType::NotFound)
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 72c9cc342b339779cd6d61a8e3349aeff5cad2ff
|
||||
Subproject commit 29ffa99df0f487fda2037f49e8683129cedae066
|
|
@ -115,16 +115,16 @@ pub struct NodeInfoSoftware {
|
|||
#[serde(rename_all = "camelCase", default)]
|
||||
pub struct NodeInfoUsage {
|
||||
pub users: Option<NodeInfoUsers>,
|
||||
pub local_posts: Option<i64>,
|
||||
pub local_comments: Option<i64>,
|
||||
pub local_posts: Option<i32>,
|
||||
pub local_comments: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[serde(rename_all = "camelCase", default)]
|
||||
pub struct NodeInfoUsers {
|
||||
pub total: Option<i64>,
|
||||
pub active_halfyear: Option<i64>,
|
||||
pub active_month: Option<i64>,
|
||||
pub total: Option<i32>,
|
||||
pub active_halfyear: Option<i32>,
|
||||
pub active_month: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
|
|
|
@ -6,7 +6,7 @@ use diesel::{
|
|||
dsl::{count, exists, not, update, IntervalDsl},
|
||||
query_builder::AsQuery,
|
||||
sql_query,
|
||||
sql_types::{Integer, Timestamptz},
|
||||
sql_types::{BigInt, Timestamptz},
|
||||
BoolExpressionMethods,
|
||||
ExpressionMethods,
|
||||
NullableExpressionMethods,
|
||||
|
@ -47,7 +47,10 @@ use lemmy_db_schema_file::schema::{
|
|||
site,
|
||||
};
|
||||
use lemmy_db_views_site::SiteView;
|
||||
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyErrorType, LemmyResult},
|
||||
DB_BATCH_SIZE,
|
||||
};
|
||||
use reqwest_middleware::ClientWithMiddleware;
|
||||
use std::time::Duration;
|
||||
use tracing::{info, warn};
|
||||
|
@ -140,12 +143,12 @@ pub async fn setup(context: Data<LemmyContext>) -> LemmyResult<()> {
|
|||
async fn update_hot_ranks(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
||||
info!("Updating hot ranks for all history...");
|
||||
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
process_post_aggregates_ranks_in_batches(&mut conn).await?;
|
||||
process_post_aggregates_ranks_in_batches(conn).await?;
|
||||
|
||||
process_ranks_in_batches(
|
||||
&mut conn,
|
||||
conn,
|
||||
"comment",
|
||||
"a.hot_rank != 0",
|
||||
"SET hot_rank = r.hot_rank(a.score, a.published_at)",
|
||||
|
@ -153,7 +156,7 @@ async fn update_hot_ranks(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
|||
.await?;
|
||||
|
||||
process_ranks_in_batches(
|
||||
&mut conn,
|
||||
conn,
|
||||
"community",
|
||||
"a.hot_rank != 0",
|
||||
"SET hot_rank = r.hot_rank(a.subscribers, a.published_at)",
|
||||
|
@ -182,7 +185,6 @@ async fn process_ranks_in_batches(
|
|||
) -> LemmyResult<()> {
|
||||
let process_start_time: DateTime<Utc> = Utc.timestamp_opt(0, 0).single().unwrap_or_default();
|
||||
|
||||
let update_batch_size = 1000; // Bigger batches than this tend to cause seq scans
|
||||
let mut processed_rows_count = 0;
|
||||
let mut previous_batch_result = Some(process_start_time);
|
||||
while let Some(previous_batch_last_published) = previous_batch_result {
|
||||
|
@ -200,7 +202,7 @@ async fn process_ranks_in_batches(
|
|||
"#,
|
||||
))
|
||||
.bind::<Timestamptz, _>(previous_batch_last_published)
|
||||
.bind::<Integer, _>(update_batch_size)
|
||||
.bind::<BigInt, _>(DB_BATCH_SIZE)
|
||||
.get_results::<HotRanksUpdateResult>(conn)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
|
@ -222,7 +224,6 @@ async fn process_ranks_in_batches(
|
|||
async fn process_post_aggregates_ranks_in_batches(conn: &mut AsyncPgConnection) -> LemmyResult<()> {
|
||||
let process_start_time: DateTime<Utc> = Utc.timestamp_opt(0, 0).single().unwrap_or_default();
|
||||
|
||||
let update_batch_size = 1000; // Bigger batches than this tend to cause seq scans
|
||||
let mut processed_rows_count = 0;
|
||||
let mut previous_batch_result = Some(process_start_time);
|
||||
while let Some(previous_batch_last_published) = previous_batch_result {
|
||||
|
@ -245,7 +246,7 @@ async fn process_post_aggregates_ranks_in_batches(conn: &mut AsyncPgConnection)
|
|||
"#,
|
||||
)
|
||||
.bind::<Timestamptz, _>(previous_batch_last_published)
|
||||
.bind::<Integer, _>(update_batch_size)
|
||||
.bind::<BigInt, _>(DB_BATCH_SIZE)
|
||||
.get_results::<HotRanksUpdateResult>(conn)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
|
@ -263,12 +264,12 @@ async fn process_post_aggregates_ranks_in_batches(conn: &mut AsyncPgConnection)
|
|||
}
|
||||
|
||||
async fn delete_expired_captcha_answers(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
diesel::delete(
|
||||
captcha_answer::table.filter(captcha_answer::published_at.lt(now() - IntervalDsl::minutes(10))),
|
||||
)
|
||||
.execute(&mut conn)
|
||||
.execute(conn)
|
||||
.await?;
|
||||
info!("Done.");
|
||||
|
||||
|
@ -278,19 +279,19 @@ async fn delete_expired_captcha_answers(pool: &mut DbPool<'_>) -> LemmyResult<()
|
|||
/// Clear old activities (this table gets very large)
|
||||
async fn clear_old_activities(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
||||
info!("Clearing old activities...");
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
diesel::delete(
|
||||
sent_activity::table.filter(sent_activity::published_at.lt(now() - IntervalDsl::days(7))),
|
||||
)
|
||||
.execute(&mut conn)
|
||||
.execute(conn)
|
||||
.await?;
|
||||
|
||||
diesel::delete(
|
||||
received_activity::table
|
||||
.filter(received_activity::published_at.lt(now() - IntervalDsl::days(7))),
|
||||
)
|
||||
.execute(&mut conn)
|
||||
.execute(conn)
|
||||
.await?;
|
||||
info!("Done.");
|
||||
Ok(())
|
||||
|
@ -305,7 +306,7 @@ async fn delete_old_denied_users(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
|||
/// overwrite posts and comments 30d after deletion
|
||||
async fn overwrite_deleted_posts_and_comments(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
||||
info!("Overwriting deleted posts...");
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
diesel::update(
|
||||
post::table
|
||||
|
@ -317,7 +318,7 @@ async fn overwrite_deleted_posts_and_comments(pool: &mut DbPool<'_>) -> LemmyRes
|
|||
post::body.eq(DELETED_REPLACEMENT_TEXT),
|
||||
post::name.eq(DELETED_REPLACEMENT_TEXT),
|
||||
))
|
||||
.execute(&mut conn)
|
||||
.execute(conn)
|
||||
.await?;
|
||||
|
||||
info!("Overwriting deleted comments...");
|
||||
|
@ -328,7 +329,7 @@ async fn overwrite_deleted_posts_and_comments(pool: &mut DbPool<'_>) -> LemmyRes
|
|||
.filter(comment::content.ne(DELETED_REPLACEMENT_TEXT)),
|
||||
)
|
||||
.set(comment::content.eq(DELETED_REPLACEMENT_TEXT))
|
||||
.execute(&mut conn)
|
||||
.execute(conn)
|
||||
.await?;
|
||||
info!("Done.");
|
||||
Ok(())
|
||||
|
@ -338,7 +339,7 @@ async fn overwrite_deleted_posts_and_comments(pool: &mut DbPool<'_>) -> LemmyRes
|
|||
async fn active_counts(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
||||
info!("Updating active site and community aggregates ...");
|
||||
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
let intervals = vec![
|
||||
("1 day", "day"),
|
||||
|
@ -352,20 +353,16 @@ async fn active_counts(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
|||
"update local_site set users_active_{} = (select r.site_aggregates_activity('{}')) where site_id = 1",
|
||||
abbr, full_form
|
||||
);
|
||||
sql_query(update_site_stmt).execute(&mut conn).await?;
|
||||
sql_query(update_site_stmt).execute(conn).await?;
|
||||
|
||||
let update_community_stmt = format!("update community ca set users_active_{} = mv.count_ from r.community_aggregates_activity('{}') mv where ca.id = mv.community_id_", abbr, full_form);
|
||||
sql_query(update_community_stmt).execute(&mut conn).await?;
|
||||
sql_query(update_community_stmt).execute(conn).await?;
|
||||
}
|
||||
|
||||
let update_interactions_stmt = "update community ca set interactions_month = mv.count_ from r.community_aggregates_interactions('1 month') mv where ca.id = mv.community_id_";
|
||||
sql_query(update_interactions_stmt)
|
||||
.execute(&mut conn)
|
||||
.await?;
|
||||
sql_query(update_interactions_stmt).execute(conn).await?;
|
||||
|
||||
let mut conn = get_conn(pool).await?;
|
||||
|
||||
let user_count: i64 = local_user::table
|
||||
let user_count = local_user::table
|
||||
.inner_join(
|
||||
person::table.left_join(
|
||||
instance_actions::table
|
||||
|
@ -378,12 +375,13 @@ async fn active_counts(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
|||
.filter(instance_actions::received_ban_at.is_null())
|
||||
.filter(not(person::deleted))
|
||||
.select(count(local_user::id))
|
||||
.get_result(&mut conn)
|
||||
.await?;
|
||||
.first::<i64>(conn)
|
||||
.await
|
||||
.map(i32::try_from)??;
|
||||
|
||||
update(local_site::table)
|
||||
.set((local_site::users.eq(user_count),))
|
||||
.execute(&mut conn)
|
||||
.set(local_site::users.eq(user_count))
|
||||
.execute(conn)
|
||||
.await?;
|
||||
|
||||
info!("Done.");
|
||||
|
@ -393,20 +391,20 @@ async fn active_counts(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
|||
/// Set banned to false after ban expires
|
||||
async fn update_banned_when_expired(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
||||
info!("Updating banned column if it expires ...");
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
uplete(community_actions::table.filter(community_actions::ban_expires_at.lt(now().nullable())))
|
||||
.set_null(community_actions::received_ban_at)
|
||||
.set_null(community_actions::ban_expires_at)
|
||||
.as_query()
|
||||
.execute(&mut conn)
|
||||
.execute(conn)
|
||||
.await?;
|
||||
|
||||
uplete(instance_actions::table.filter(instance_actions::ban_expires_at.lt(now().nullable())))
|
||||
.set_null(instance_actions::received_ban_at)
|
||||
.set_null(instance_actions::ban_expires_at)
|
||||
.as_query()
|
||||
.execute(&mut conn)
|
||||
.execute(conn)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -414,12 +412,12 @@ async fn update_banned_when_expired(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
|||
/// Set banned to false after ban expires
|
||||
async fn delete_instance_block_when_expired(pool: &mut DbPool<'_>) -> LemmyResult<()> {
|
||||
info!("Delete instance blocks when expired ...");
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
diesel::delete(
|
||||
federation_blocklist::table.filter(federation_blocklist::expires_at.lt(now().nullable())),
|
||||
)
|
||||
.execute(&mut conn)
|
||||
.execute(conn)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -428,7 +426,7 @@ async fn delete_instance_block_when_expired(pool: &mut DbPool<'_>) -> LemmyResul
|
|||
async fn publish_scheduled_posts(context: &Data<LemmyContext>) -> LemmyResult<()> {
|
||||
let pool = &mut context.pool();
|
||||
let local_instance_id = SiteView::read_local(pool).await?.instance.id;
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
let not_community_banned_action = community_actions::table
|
||||
.find((person::id, community::id))
|
||||
|
@ -453,7 +451,7 @@ async fn publish_scheduled_posts(context: &Data<LemmyContext>) -> LemmyResult<()
|
|||
// ensure that user isnt banned from local
|
||||
.filter(not(exists(not_local_banned_action)))
|
||||
.select((post::all_columns, community::all_columns))
|
||||
.get_results::<(Post, Community)>(&mut conn)
|
||||
.get_results::<(Post, Community)>(conn)
|
||||
.await?;
|
||||
|
||||
for (post, community) in scheduled_posts {
|
||||
|
@ -483,9 +481,9 @@ async fn update_instance_software(
|
|||
client: &ClientWithMiddleware,
|
||||
) -> LemmyResult<()> {
|
||||
info!("Updating instances software and versions...");
|
||||
let mut conn = get_conn(pool).await?;
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
let instances = instance::table.get_results::<Instance>(&mut conn).await?;
|
||||
let instances = instance::table.get_results::<Instance>(conn).await?;
|
||||
|
||||
for instance in instances {
|
||||
if let Some(form) = build_update_instance_form(&instance.domain, client).await {
|
||||
|
|
|
@ -49,6 +49,9 @@ pub const CACHE_DURATION_LARGEST_COMMUNITY: Duration = DAY;
|
|||
|
||||
pub const MAX_COMMENT_DEPTH_LIMIT: usize = 50;
|
||||
|
||||
/// Doing DB transactions of bigger batches than this tend to cause seq scans.
|
||||
pub const DB_BATCH_SIZE: i64 = 1000;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! location_info {
|
||||
() => {
|
||||
|
|
|
@ -4,11 +4,15 @@ use deser_hjson::from_str;
|
|||
use std::{env, fs, sync::LazyLock};
|
||||
use structs::{PictrsConfig, Settings};
|
||||
use url::Url;
|
||||
use urlencoding::encode;
|
||||
|
||||
pub mod structs;
|
||||
|
||||
static DEFAULT_CONFIG_FILE: &str = "config/config.hjson";
|
||||
|
||||
/// Some connection options to speed up queries
|
||||
const CONNECTION_OPTIONS: [&str; 1] = ["geqo_threshold=12"];
|
||||
|
||||
#[allow(clippy::expect_used)]
|
||||
pub static SETTINGS: LazyLock<Settings> = LazyLock::new(|| {
|
||||
if env::var("LEMMY_INITIALIZE_WITH_DEFAULT_SETTINGS").is_ok() {
|
||||
|
@ -84,6 +88,30 @@ impl Settings {
|
|||
.clone()
|
||||
.ok_or_else(|| anyhow!("images_disabled").into())
|
||||
}
|
||||
|
||||
/// Sets a few additional config options necessary for starting lemmy
|
||||
pub fn get_database_url_with_options(&self) -> LemmyResult<String> {
|
||||
let mut url = Url::parse(&self.get_database_url())?;
|
||||
|
||||
// Set `lemmy.protocol_and_hostname` so triggers can use it
|
||||
let lemmy_protocol_and_hostname_option =
|
||||
"lemmy.protocol_and_hostname=".to_owned() + &self.get_protocol_and_hostname();
|
||||
let mut options = CONNECTION_OPTIONS.to_vec();
|
||||
options.push(&lemmy_protocol_and_hostname_option);
|
||||
|
||||
// Create the connection uri portion
|
||||
let options_segments = options
|
||||
.iter()
|
||||
// The equal signs need to be encoded, since the url set_query doesn't do them,
|
||||
// and postgres requires them to be %3D
|
||||
// https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
|
||||
.map(|o| format!("-c {}", encode(o)))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ");
|
||||
|
||||
url.set_query(Some(&format!("options={options_segments}")));
|
||||
Ok(url.into())
|
||||
}
|
||||
}
|
||||
#[allow(clippy::expect_used)]
|
||||
/// Necessary to avoid URL expect failures
|
||||
|
|
|
@ -18,8 +18,18 @@ effective_io_concurrency = 200
|
|||
work_mem = 3932kB
|
||||
huge_pages = try
|
||||
min_wal_size = 1GB
|
||||
max_wal_size = 4GB
|
||||
max_wal_size = 8GB
|
||||
max_worker_processes = 16
|
||||
max_parallel_workers_per_gather = 4
|
||||
max_parallel_workers = 16
|
||||
max_parallel_maintenance_workers = 4
|
||||
|
||||
# Listen address
|
||||
listen_addresses = '*'
|
||||
|
||||
# Logging
|
||||
session_preload_libraries = auto_explain
|
||||
auto_explain.log_min_duration = 5ms
|
||||
auto_explain.log_analyze = true
|
||||
auto_explain.log_triggers = true
|
||||
track_activity_query_size = 1048576
|
||||
|
|
|
@ -88,20 +88,7 @@ services:
|
|||
# You can use this technique to add them here
|
||||
# https://stackoverflow.com/a/30850095/1655478
|
||||
hostname: postgres
|
||||
command:
|
||||
[
|
||||
"postgres",
|
||||
"-c",
|
||||
"session_preload_libraries=auto_explain",
|
||||
"-c",
|
||||
"auto_explain.log_min_duration=5ms",
|
||||
"-c",
|
||||
"auto_explain.log_analyze=true",
|
||||
"-c",
|
||||
"auto_explain.log_triggers=true",
|
||||
"-c",
|
||||
"track_activity_query_size=1048576",
|
||||
]
|
||||
command: postgres -c config_file=/etc/postgresql.conf
|
||||
ports:
|
||||
# use a different port so it doesn't conflict with potential postgres db running on the host
|
||||
- "5433:5432"
|
||||
|
|
|
@ -86,7 +86,7 @@ FROM
|
|||
WHERE
|
||||
blocked IS NOT NULL;
|
||||
|
||||
CREATE TABLE person_post_aggregates (
|
||||
CREATE TABLE IF NOT EXISTS person_post_aggregates (
|
||||
person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
read_comments bigint DEFAULT 0 NOT NULL,
|
||||
|
@ -122,7 +122,7 @@ FROM
|
|||
WHERE
|
||||
hidden IS NOT NULL;
|
||||
|
||||
CREATE TABLE post_like (
|
||||
CREATE TABLE IF NOT EXISTS post_like (
|
||||
post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
score smallint NOT NULL,
|
||||
|
@ -174,7 +174,24 @@ WHERE followed IS NULL;
|
|||
DELETE FROM post_actions
|
||||
WHERE read IS NULL;
|
||||
|
||||
ALTER TABLE comment_actions RENAME TO comment_like;
|
||||
CREATE TABLE IF NOT EXISTS comment_like (
|
||||
comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
score smallint NOT NULL,
|
||||
published timestamptz DEFAULT now() NOT NULL,
|
||||
PRIMARY KEY (person_id, comment_id)
|
||||
);
|
||||
|
||||
INSERT INTO comment_like (comment_id, person_id, score, published)
|
||||
SELECT
|
||||
comment_id,
|
||||
person_id,
|
||||
like_score,
|
||||
liked
|
||||
FROM
|
||||
comment_actions
|
||||
WHERE
|
||||
liked IS NOT NULL;
|
||||
|
||||
ALTER TABLE community_actions RENAME TO community_follower;
|
||||
|
||||
|
@ -182,11 +199,22 @@ ALTER TABLE instance_actions RENAME TO instance_block;
|
|||
|
||||
ALTER TABLE person_actions RENAME TO person_follower;
|
||||
|
||||
ALTER TABLE post_actions RENAME TO post_read;
|
||||
CREATE TABLE IF NOT EXISTS post_read (
|
||||
post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
published timestamptz DEFAULT now() NOT NULL,
|
||||
PRIMARY KEY (person_id, post_id)
|
||||
);
|
||||
|
||||
ALTER TABLE comment_like RENAME COLUMN liked TO published;
|
||||
|
||||
ALTER TABLE comment_like RENAME COLUMN like_score TO score;
|
||||
INSERT INTO post_read (post_id, person_id, published)
|
||||
SELECT
|
||||
post_id,
|
||||
person_id,
|
||||
read
|
||||
FROM
|
||||
post_actions
|
||||
WHERE
|
||||
read IS NOT NULL;
|
||||
|
||||
ALTER TABLE community_follower RENAME COLUMN followed TO published;
|
||||
|
||||
|
@ -204,15 +232,6 @@ ALTER TABLE person_follower RENAME COLUMN followed TO published;
|
|||
|
||||
ALTER TABLE person_follower RENAME COLUMN follow_pending TO pending;
|
||||
|
||||
ALTER TABLE post_read RENAME COLUMN read TO published;
|
||||
|
||||
ALTER TABLE comment_like
|
||||
DROP CONSTRAINT comment_actions_check_liked,
|
||||
ALTER COLUMN published SET NOT NULL,
|
||||
ALTER COLUMN published SET DEFAULT now(),
|
||||
ALTER COLUMN score SET NOT NULL,
|
||||
DROP COLUMN saved;
|
||||
|
||||
ALTER TABLE community_follower
|
||||
DROP CONSTRAINT community_actions_check_followed,
|
||||
DROP CONSTRAINT community_actions_check_received_ban,
|
||||
|
@ -235,27 +254,7 @@ ALTER TABLE person_follower
|
|||
ALTER COLUMN pending SET NOT NULL,
|
||||
DROP COLUMN blocked;
|
||||
|
||||
ALTER TABLE post_read
|
||||
DROP CONSTRAINT post_actions_check_read_comments,
|
||||
DROP CONSTRAINT post_actions_check_liked,
|
||||
ALTER COLUMN published SET NOT NULL,
|
||||
ALTER COLUMN published SET DEFAULT now(),
|
||||
DROP COLUMN read_comments,
|
||||
DROP COLUMN read_comments_amount,
|
||||
DROP COLUMN saved,
|
||||
DROP COLUMN liked,
|
||||
DROP COLUMN like_score,
|
||||
DROP COLUMN hidden;
|
||||
|
||||
-- Rename associated stuff
|
||||
ALTER INDEX comment_actions_pkey RENAME TO comment_like_pkey;
|
||||
|
||||
ALTER INDEX idx_comment_actions_comment RENAME TO idx_comment_like_comment;
|
||||
|
||||
ALTER TABLE comment_like RENAME CONSTRAINT comment_actions_comment_id_fkey TO comment_like_comment_id_fkey;
|
||||
|
||||
ALTER TABLE comment_like RENAME CONSTRAINT comment_actions_person_id_fkey TO comment_like_person_id_fkey;
|
||||
|
||||
ALTER INDEX community_actions_pkey RENAME TO community_follower_pkey;
|
||||
|
||||
ALTER INDEX idx_community_actions_community RENAME TO idx_community_follower_community;
|
||||
|
@ -278,12 +277,6 @@ ALTER TABLE person_follower RENAME CONSTRAINT person_actions_target_id_fkey TO p
|
|||
|
||||
ALTER TABLE person_follower RENAME CONSTRAINT person_actions_person_id_fkey TO person_follower_follower_id_fkey;
|
||||
|
||||
ALTER INDEX post_actions_pkey RENAME TO post_read_pkey;
|
||||
|
||||
ALTER TABLE post_read RENAME CONSTRAINT post_actions_person_id_fkey TO post_read_person_id_fkey;
|
||||
|
||||
ALTER TABLE post_read RENAME CONSTRAINT post_actions_post_id_fkey TO post_read_post_id_fkey;
|
||||
|
||||
-- Rename idx_community_actions_followed and remove filter
|
||||
CREATE INDEX idx_community_follower_published ON community_follower (published);
|
||||
|
||||
|
@ -304,17 +297,21 @@ CREATE INDEX idx_person_block_person ON person_block (person_id);
|
|||
|
||||
CREATE INDEX idx_person_block_target ON person_block (target_id);
|
||||
|
||||
CREATE INDEX idx_person_post_aggregates_person ON person_post_aggregates (person_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_person_post_aggregates_person ON person_post_aggregates (person_id);
|
||||
|
||||
CREATE INDEX idx_person_post_aggregates_post ON person_post_aggregates (post_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_person_post_aggregates_post ON person_post_aggregates (post_id);
|
||||
|
||||
CREATE INDEX idx_post_like_post ON post_like (post_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_like_post ON post_like (post_id);
|
||||
|
||||
CREATE INDEX idx_comment_like_comment ON comment_like (comment_id);
|
||||
|
||||
DROP INDEX idx_person_actions_person, idx_person_actions_target, idx_post_actions_person, idx_post_actions_post;
|
||||
|
||||
-- Drop `NOT NULL` indexes of columns that still exist
|
||||
DROP INDEX idx_comment_actions_liked_not_null, idx_community_actions_followed_not_null, idx_person_actions_followed_not_null, idx_post_actions_read_not_null, idx_instance_actions_blocked_not_null;
|
||||
DROP INDEX idx_comment_actions_liked_not_null, idx_community_actions_followed_not_null, idx_person_actions_followed_not_null, idx_post_actions_read_not_null, idx_instance_actions_blocked_not_null, idx_comment_actions_person, idx_community_actions_person, idx_instance_actions_instance, idx_instance_actions_person;
|
||||
|
||||
-- Drop statistics of columns that still exist
|
||||
DROP statistics comment_actions_liked_stat, community_actions_followed_stat, person_actions_followed_stat;
|
||||
|
||||
DROP TABLE comment_actions, post_actions;
|
||||
|
||||
|
|
|
@ -1,352 +1,55 @@
|
|||
-- For each new actions table, transform the table previously used for the most common action type
|
||||
-- into the new actions table, which should only change the table's metadata instead of rewriting the
|
||||
-- rows
|
||||
ALTER TABLE comment_like RENAME TO comment_actions;
|
||||
|
||||
ALTER TABLE community_follower RENAME TO community_actions;
|
||||
|
||||
ALTER TABLE instance_block RENAME TO instance_actions;
|
||||
|
||||
ALTER TABLE person_follower RENAME TO person_actions;
|
||||
|
||||
ALTER TABLE post_read RENAME TO post_actions;
|
||||
|
||||
ALTER TABLE comment_actions RENAME COLUMN published TO liked;
|
||||
|
||||
ALTER TABLE comment_actions RENAME COLUMN score TO like_score;
|
||||
|
||||
ALTER TABLE community_actions RENAME COLUMN published TO followed;
|
||||
|
||||
ALTER TABLE community_actions RENAME COLUMN state TO follow_state;
|
||||
|
||||
ALTER TABLE community_actions RENAME COLUMN approver_id TO follow_approver_id;
|
||||
|
||||
ALTER TABLE instance_actions RENAME COLUMN published TO blocked;
|
||||
|
||||
ALTER TABLE person_actions RENAME COLUMN person_id TO target_id;
|
||||
|
||||
ALTER TABLE person_actions RENAME COLUMN follower_id TO person_id;
|
||||
|
||||
ALTER TABLE person_actions RENAME COLUMN published TO followed;
|
||||
|
||||
ALTER TABLE person_actions RENAME COLUMN pending TO follow_pending;
|
||||
|
||||
ALTER TABLE post_actions RENAME COLUMN published TO read;
|
||||
|
||||
-- Mark all constraints of affected tables as deferrable to speed up migration
|
||||
ALTER TABLE community_actions
|
||||
ALTER CONSTRAINT community_follower_community_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE community_actions
|
||||
ALTER CONSTRAINT community_follower_approver_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE community_actions
|
||||
ALTER CONSTRAINT community_follower_person_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE comment_actions
|
||||
ALTER CONSTRAINT comment_like_comment_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE comment_actions
|
||||
ALTER CONSTRAINT comment_like_person_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE instance_actions
|
||||
ALTER CONSTRAINT instance_block_instance_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE instance_actions
|
||||
ALTER CONSTRAINT instance_block_person_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE person_actions
|
||||
ALTER CONSTRAINT person_follower_follower_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE person_actions
|
||||
ALTER CONSTRAINT person_follower_person_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE post_actions
|
||||
ALTER CONSTRAINT post_read_person_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE post_actions
|
||||
ALTER CONSTRAINT post_read_post_id_fkey DEFERRABLE;
|
||||
|
||||
ALTER TABLE comment_actions
|
||||
ALTER COLUMN liked DROP NOT NULL,
|
||||
ALTER COLUMN liked DROP DEFAULT,
|
||||
ALTER COLUMN like_score DROP NOT NULL,
|
||||
ADD COLUMN saved timestamptz;
|
||||
|
||||
ALTER TABLE community_actions
|
||||
ALTER COLUMN followed DROP NOT NULL,
|
||||
ALTER COLUMN followed DROP DEFAULT,
|
||||
ALTER COLUMN follow_state DROP NOT NULL,
|
||||
ADD COLUMN blocked timestamptz,
|
||||
ADD COLUMN became_moderator timestamptz,
|
||||
ADD COLUMN received_ban timestamptz,
|
||||
ADD COLUMN ban_expires timestamptz;
|
||||
|
||||
ALTER TABLE instance_actions
|
||||
ALTER COLUMN blocked DROP NOT NULL,
|
||||
ALTER COLUMN blocked DROP DEFAULT;
|
||||
|
||||
ALTER TABLE person_actions
|
||||
ALTER COLUMN followed DROP NOT NULL,
|
||||
ALTER COLUMN followed DROP DEFAULT,
|
||||
ALTER COLUMN follow_pending DROP NOT NULL,
|
||||
ADD COLUMN blocked timestamptz;
|
||||
|
||||
ALTER TABLE post_actions
|
||||
ALTER COLUMN read DROP NOT NULL,
|
||||
ALTER COLUMN read DROP DEFAULT,
|
||||
ADD COLUMN read_comments timestamptz,
|
||||
ADD COLUMN read_comments_amount bigint,
|
||||
ADD COLUMN saved timestamptz,
|
||||
ADD COLUMN liked timestamptz,
|
||||
ADD COLUMN like_score smallint,
|
||||
ADD COLUMN hidden timestamptz;
|
||||
|
||||
-- Add actions from other old tables to the new tables
|
||||
INSERT INTO comment_actions (person_id, comment_id, saved)
|
||||
-- Consolidates all the old tables like post_read, post_like, into post_actions, to reduce joins and increase performance.
|
||||
-- This creates the tables:
|
||||
-- post_actions, comment_actions, community_actions, instance_actions, and person_actions.
|
||||
--
|
||||
-- comment_actions
|
||||
CREATE TABLE comment_actions AS
|
||||
SELECT
|
||||
person_id,
|
||||
comment_id,
|
||||
published
|
||||
FROM
|
||||
comment_saved
|
||||
ON CONFLICT (person_id,
|
||||
comment_id)
|
||||
DO UPDATE SET
|
||||
saved = excluded.saved;
|
||||
|
||||
INSERT INTO person_actions (person_id, target_id, blocked)
|
||||
SELECT
|
||||
person_id,
|
||||
target_id,
|
||||
published
|
||||
FROM
|
||||
person_block
|
||||
ON CONFLICT (person_id,
|
||||
target_id)
|
||||
DO UPDATE SET
|
||||
blocked = excluded.blocked;
|
||||
|
||||
UPDATE
|
||||
community_actions AS a
|
||||
SET
|
||||
blocked = (
|
||||
SELECT
|
||||
published
|
||||
FROM
|
||||
community_block AS b
|
||||
WHERE (b.person_id, b.community_id) = (a.person_id, a.community_id)),
|
||||
became_moderator = (
|
||||
cast(max(like_score) AS smallint) AS like_score,
|
||||
max(liked) AS liked,
|
||||
max(saved) AS saved
|
||||
FROM (
|
||||
SELECT
|
||||
person_id,
|
||||
comment_id,
|
||||
score AS like_score,
|
||||
published AS liked,
|
||||
NULL::timestamptz AS saved
|
||||
FROM
|
||||
comment_like
|
||||
UNION ALL
|
||||
SELECT
|
||||
person_id,
|
||||
comment_id,
|
||||
NULL::int,
|
||||
NULL::timestamptz,
|
||||
published
|
||||
FROM
|
||||
community_moderator AS b
|
||||
WHERE (b.person_id, b.community_id) = (a.person_id, a.community_id)),
|
||||
(received_ban,
|
||||
ban_expires) = (
|
||||
SELECT
|
||||
published,
|
||||
expires
|
||||
FROM
|
||||
community_person_ban AS b
|
||||
WHERE (b.person_id, b.community_id) = (a.person_id, a.community_id));
|
||||
|
||||
INSERT INTO community_actions (person_id, community_id, received_ban, ban_expires)
|
||||
SELECT
|
||||
comment_saved)
|
||||
GROUP BY
|
||||
person_id,
|
||||
community_id,
|
||||
published,
|
||||
expires
|
||||
FROM
|
||||
community_person_ban AS b
|
||||
WHERE
|
||||
NOT EXISTS (
|
||||
SELECT
|
||||
FROM
|
||||
community_actions AS a
|
||||
WHERE (a.person_id, a.community_id) = (b.person_id, b.community_id));
|
||||
comment_id;
|
||||
|
||||
INSERT INTO community_actions (person_id, community_id, blocked)
|
||||
SELECT
|
||||
person_id,
|
||||
community_id,
|
||||
published
|
||||
FROM
|
||||
community_block
|
||||
ON CONFLICT (person_id,
|
||||
community_id)
|
||||
DO UPDATE SET
|
||||
blocked = excluded.blocked
|
||||
WHERE
|
||||
community_actions.blocked IS NULL;
|
||||
-- Drop the tables
|
||||
DROP TABLE comment_saved, comment_like;
|
||||
|
||||
INSERT INTO community_actions (person_id, community_id, became_moderator)
|
||||
SELECT
|
||||
person_id,
|
||||
community_id,
|
||||
published
|
||||
FROM
|
||||
community_moderator
|
||||
ON CONFLICT (person_id,
|
||||
community_id)
|
||||
DO UPDATE SET
|
||||
became_moderator = excluded.became_moderator
|
||||
WHERE
|
||||
community_actions.became_moderator IS NULL;
|
||||
|
||||
UPDATE
|
||||
post_actions AS a
|
||||
SET
|
||||
(read_comments,
|
||||
read_comments_amount) = (
|
||||
SELECT
|
||||
published,
|
||||
read_comments
|
||||
FROM
|
||||
person_post_aggregates AS b
|
||||
WHERE (b.person_id, b.post_id) = (a.person_id, a.post_id)),
|
||||
hidden = (
|
||||
SELECT
|
||||
published
|
||||
FROM
|
||||
post_hide AS b
|
||||
WHERE (b.person_id, b.post_id) = (a.person_id, a.post_id)),
|
||||
(liked,
|
||||
like_score) = (
|
||||
SELECT
|
||||
published,
|
||||
score
|
||||
FROM
|
||||
post_like AS b
|
||||
WHERE (b.person_id, b.post_id) = (a.person_id, a.post_id)),
|
||||
saved = (
|
||||
SELECT
|
||||
published
|
||||
FROM
|
||||
post_saved AS b
|
||||
WHERE (b.person_id, b.post_id) = (a.person_id, a.post_id));
|
||||
|
||||
INSERT INTO post_actions (person_id, post_id, liked, like_score)
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
published,
|
||||
score
|
||||
FROM
|
||||
post_like AS b
|
||||
WHERE
|
||||
NOT EXISTS (
|
||||
SELECT
|
||||
FROM
|
||||
post_actions AS a
|
||||
WHERE (a.person_id, a.post_id) = (b.person_id, b.post_id));
|
||||
|
||||
INSERT INTO post_actions (person_id, post_id, read_comments, read_comments_amount)
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
published,
|
||||
read_comments
|
||||
FROM
|
||||
person_post_aggregates
|
||||
ON CONFLICT (person_id,
|
||||
post_id)
|
||||
DO UPDATE SET
|
||||
read_comments = excluded.read_comments,
|
||||
read_comments_amount = excluded.read_comments_amount
|
||||
WHERE
|
||||
post_actions.read_comments IS NULL;
|
||||
|
||||
INSERT INTO post_actions (person_id, post_id, saved)
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
published
|
||||
FROM
|
||||
post_saved
|
||||
ON CONFLICT (person_id,
|
||||
post_id)
|
||||
DO UPDATE SET
|
||||
saved = excluded.saved
|
||||
WHERE
|
||||
post_actions.saved IS NULL;
|
||||
|
||||
INSERT INTO post_actions (person_id, post_id, hidden)
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
published
|
||||
FROM
|
||||
post_hide
|
||||
ON CONFLICT (person_id,
|
||||
post_id)
|
||||
DO UPDATE SET
|
||||
hidden = excluded.hidden
|
||||
WHERE
|
||||
post_actions.hidden IS NULL;
|
||||
|
||||
-- Drop old tables
|
||||
DROP TABLE comment_saved, community_block, community_moderator, community_person_ban, person_block, person_post_aggregates, post_hide, post_like, post_saved;
|
||||
|
||||
-- Rename associated stuff
|
||||
ALTER INDEX comment_like_pkey RENAME TO comment_actions_pkey;
|
||||
|
||||
ALTER INDEX idx_comment_like_comment RENAME TO idx_comment_actions_comment;
|
||||
|
||||
ALTER TABLE comment_actions RENAME CONSTRAINT comment_like_comment_id_fkey TO comment_actions_comment_id_fkey;
|
||||
|
||||
ALTER TABLE comment_actions RENAME CONSTRAINT comment_like_person_id_fkey TO comment_actions_person_id_fkey;
|
||||
|
||||
ALTER INDEX community_follower_pkey RENAME TO community_actions_pkey;
|
||||
|
||||
ALTER INDEX idx_community_follower_community RENAME TO idx_community_actions_community;
|
||||
|
||||
ALTER TABLE community_actions RENAME CONSTRAINT community_follower_community_id_fkey TO community_actions_community_id_fkey;
|
||||
|
||||
ALTER TABLE community_actions RENAME CONSTRAINT community_follower_person_id_fkey TO community_actions_person_id_fkey;
|
||||
|
||||
ALTER TABLE community_actions RENAME CONSTRAINT community_follower_approver_id_fkey TO community_actions_follow_approver_id_fkey;
|
||||
|
||||
ALTER INDEX instance_block_pkey RENAME TO instance_actions_pkey;
|
||||
|
||||
ALTER TABLE instance_actions RENAME CONSTRAINT instance_block_instance_id_fkey TO instance_actions_instance_id_fkey;
|
||||
|
||||
ALTER TABLE instance_actions RENAME CONSTRAINT instance_block_person_id_fkey TO instance_actions_person_id_fkey;
|
||||
|
||||
ALTER INDEX person_follower_pkey RENAME TO person_actions_pkey;
|
||||
|
||||
ALTER TABLE person_actions RENAME CONSTRAINT person_follower_person_id_fkey TO person_actions_target_id_fkey;
|
||||
|
||||
ALTER TABLE person_actions RENAME CONSTRAINT person_follower_follower_id_fkey TO person_actions_person_id_fkey;
|
||||
|
||||
ALTER INDEX post_read_pkey RENAME TO post_actions_pkey;
|
||||
|
||||
ALTER TABLE post_actions RENAME CONSTRAINT post_read_person_id_fkey TO post_actions_person_id_fkey;
|
||||
|
||||
ALTER TABLE post_actions RENAME CONSTRAINT post_read_post_id_fkey TO post_actions_post_id_fkey;
|
||||
|
||||
-- Rename idx_community_follower_published and add filter
|
||||
CREATE INDEX idx_community_actions_followed ON community_actions (followed)
|
||||
WHERE
|
||||
followed IS NOT NULL;
|
||||
|
||||
DROP INDEX idx_community_follower_published;
|
||||
|
||||
-- Restore indexes of dropped tables
|
||||
CREATE INDEX idx_community_actions_became_moderator ON community_actions (became_moderator)
|
||||
WHERE
|
||||
became_moderator IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_person_actions_person ON person_actions (person_id);
|
||||
|
||||
CREATE INDEX idx_person_actions_target ON person_actions (target_id);
|
||||
|
||||
CREATE INDEX idx_post_actions_person ON post_actions (person_id);
|
||||
|
||||
CREATE INDEX idx_post_actions_post ON post_actions (post_id);
|
||||
-- Add the constraints
|
||||
ALTER TABLE comment_actions
|
||||
ALTER COLUMN person_id SET NOT NULL,
|
||||
ALTER COLUMN comment_id SET NOT NULL,
|
||||
ADD PRIMARY KEY (person_id, comment_id),
|
||||
ADD CONSTRAINT comment_actions_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT comment_actions_comment_id_fkey FOREIGN KEY (comment_id) REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT comment_actions_check_liked CHECK (((liked IS NULL) = (like_score IS NULL)));
|
||||
|
||||
-- Create new indexes, with `OR` being used to allow `IS NOT NULL` filters in queries to use either column in
|
||||
-- a group (e.g. `liked IS NOT NULL` and `like_score IS NOT NULL` both work)
|
||||
CREATE INDEX idx_comment_actions_person ON comment_actions (person_id);
|
||||
|
||||
CREATE INDEX idx_comment_actions_comment ON comment_actions (comment_id);
|
||||
|
||||
CREATE INDEX idx_comment_actions_liked_not_null ON comment_actions (person_id, comment_id)
|
||||
WHERE
|
||||
liked IS NOT NULL OR like_score IS NOT NULL;
|
||||
|
@ -355,29 +58,106 @@ CREATE INDEX idx_comment_actions_saved_not_null ON comment_actions (person_id, c
|
|||
WHERE
|
||||
saved IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_community_actions_followed_not_null ON community_actions (person_id, community_id)
|
||||
WHERE
|
||||
followed IS NOT NULL OR follow_state IS NOT NULL;
|
||||
-- Here's an SO link on merges, but this turned out to be slower than a
|
||||
-- disabled triggers + disabled primary key + full union select + insert with group by
|
||||
-- SO link on merges: https://stackoverflow.com/a/74066614/1655478
|
||||
CREATE TABLE post_actions AS
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
max(read) AS read,
|
||||
max(read_comments) AS read_comments,
|
||||
cast(max(read_comments_amount) AS int) AS read_comments_amount,
|
||||
max(saved) AS saved,
|
||||
max(liked) AS liked,
|
||||
cast(max(like_score) AS smallint) AS like_score,
|
||||
max(hidden) AS hidden
|
||||
FROM (
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
published AS read,
|
||||
NULL::timestamptz AS read_comments,
|
||||
NULL::int AS read_comments_amount,
|
||||
NULL::timestamptz AS saved,
|
||||
NULL::timestamptz AS liked,
|
||||
NULL::int AS like_score,
|
||||
NULL::timestamptz AS hidden
|
||||
FROM
|
||||
post_read
|
||||
UNION ALL
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
NULL::timestamptz,
|
||||
published,
|
||||
read_comments,
|
||||
NULL::timestamptz,
|
||||
NULL::timestamptz,
|
||||
NULL::int,
|
||||
NULL::timestamptz
|
||||
FROM
|
||||
person_post_aggregates
|
||||
UNION ALL
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
NULL::timestamptz,
|
||||
NULL::timestamptz,
|
||||
NULL::int,
|
||||
published,
|
||||
NULL::timestamptz,
|
||||
NULL::int,
|
||||
NULL::timestamptz
|
||||
FROM
|
||||
post_saved
|
||||
UNION ALL
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
NULL::timestamptz,
|
||||
NULL::timestamptz,
|
||||
NULL::int,
|
||||
NULL::timestamptz,
|
||||
published,
|
||||
score,
|
||||
NULL::timestamptz
|
||||
FROM
|
||||
post_like
|
||||
UNION ALL
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
NULL::timestamptz,
|
||||
NULL::timestamptz,
|
||||
NULL::int,
|
||||
NULL::timestamptz,
|
||||
NULL::timestamptz,
|
||||
NULL::int,
|
||||
published
|
||||
FROM
|
||||
post_hide)
|
||||
GROUP BY
|
||||
person_id,
|
||||
post_id;
|
||||
|
||||
CREATE INDEX idx_community_actions_blocked_not_null ON community_actions (person_id, community_id)
|
||||
WHERE
|
||||
blocked IS NOT NULL;
|
||||
-- Drop the tables
|
||||
DROP TABLE post_read, person_post_aggregates, post_like, post_saved, post_hide;
|
||||
|
||||
CREATE INDEX idx_community_actions_became_moderator_not_null ON community_actions (person_id, community_id)
|
||||
WHERE
|
||||
became_moderator IS NOT NULL;
|
||||
-- Add the constraints
|
||||
ALTER TABLE post_actions
|
||||
ALTER COLUMN person_id SET NOT NULL,
|
||||
ALTER COLUMN post_id SET NOT NULL,
|
||||
ADD PRIMARY KEY (person_id, post_id),
|
||||
ADD CONSTRAINT post_actions_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT post_actions_post_id_fkey FOREIGN KEY (post_id) REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT post_actions_check_liked CHECK (((liked IS NULL) = (like_score IS NULL))),
|
||||
ADD CONSTRAINT post_actions_check_read_comments CHECK (((read_comments IS NULL) = (read_comments_amount IS NULL)));
|
||||
|
||||
CREATE INDEX idx_community_actions_received_ban_not_null ON community_actions (person_id, community_id)
|
||||
WHERE
|
||||
received_ban IS NOT NULL;
|
||||
-- Create indexes
|
||||
CREATE INDEX idx_post_actions_person ON post_actions (person_id);
|
||||
|
||||
CREATE INDEX idx_person_actions_followed_not_null ON person_actions (person_id, target_id)
|
||||
WHERE
|
||||
followed IS NOT NULL OR follow_pending IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_person_actions_blocked_not_null ON person_actions (person_id, target_id)
|
||||
WHERE
|
||||
blocked IS NOT NULL;
|
||||
CREATE INDEX idx_post_actions_post ON post_actions (post_id);
|
||||
|
||||
CREATE INDEX idx_post_actions_read_not_null ON post_actions (person_id, post_id)
|
||||
WHERE
|
||||
|
@ -399,12 +179,199 @@ CREATE INDEX idx_post_actions_hidden_not_null ON post_actions (person_id, post_i
|
|||
WHERE
|
||||
hidden IS NOT NULL;
|
||||
|
||||
-- community_actions
|
||||
CREATE TABLE community_actions AS
|
||||
SELECT
|
||||
person_id,
|
||||
community_id,
|
||||
max(followed) AS followed,
|
||||
max(follow_state) AS follow_state,
|
||||
max(follow_approver_id) AS follow_approver_id,
|
||||
max(blocked) AS blocked,
|
||||
max(became_moderator) AS became_moderator,
|
||||
max(received_ban) AS received_ban,
|
||||
max(ban_expires) AS ban_expires
|
||||
FROM (
|
||||
SELECT
|
||||
person_id,
|
||||
community_id,
|
||||
published AS followed,
|
||||
state AS follow_state,
|
||||
approver_id AS follow_approver_id,
|
||||
NULL::timestamptz AS blocked,
|
||||
NULL::timestamptz AS became_moderator,
|
||||
NULL::timestamptz AS received_ban,
|
||||
NULL::timestamptz AS ban_expires
|
||||
FROM
|
||||
community_follower
|
||||
UNION ALL
|
||||
SELECT
|
||||
person_id,
|
||||
community_id,
|
||||
NULL::timestamptz,
|
||||
NULL::community_follower_state,
|
||||
NULL::int,
|
||||
published,
|
||||
NULL::timestamptz,
|
||||
NULL::timestamptz,
|
||||
NULL::timestamptz
|
||||
FROM
|
||||
community_block
|
||||
UNION ALL
|
||||
SELECT
|
||||
person_id,
|
||||
community_id,
|
||||
NULL::timestamptz,
|
||||
NULL::community_follower_state,
|
||||
NULL::int,
|
||||
NULL::timestamptz,
|
||||
published,
|
||||
NULL::timestamptz,
|
||||
NULL::timestamptz
|
||||
FROM
|
||||
community_moderator
|
||||
UNION ALL
|
||||
SELECT
|
||||
person_id,
|
||||
community_id,
|
||||
NULL::timestamptz,
|
||||
NULL::community_follower_state,
|
||||
NULL::int,
|
||||
NULL::timestamptz,
|
||||
NULL::timestamptz,
|
||||
published,
|
||||
expires
|
||||
FROM
|
||||
community_person_ban)
|
||||
GROUP BY
|
||||
person_id,
|
||||
community_id;
|
||||
|
||||
-- Drop the old tables
|
||||
DROP TABLE community_follower, community_block, community_moderator, community_person_ban;
|
||||
|
||||
-- Add the constraints
|
||||
ALTER TABLE community_actions
|
||||
ALTER COLUMN person_id SET NOT NULL,
|
||||
ALTER COLUMN community_id SET NOT NULL,
|
||||
ADD PRIMARY KEY (person_id, community_id),
|
||||
ADD CONSTRAINT community_actions_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT community_actions_follow_approver_id_fkey FOREIGN KEY (follow_approver_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT community_actions_community_id_fkey FOREIGN KEY (community_id) REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT community_actions_check_followed CHECK ((((followed IS NULL) = (follow_state IS NULL)) AND (NOT ((followed IS NULL) AND (follow_approver_id IS NOT NULL))))),
|
||||
ADD CONSTRAINT community_actions_check_received_ban CHECK ((NOT ((received_ban IS NULL) AND (ban_expires IS NOT NULL))));
|
||||
|
||||
-- Create indexes
|
||||
CREATE INDEX idx_community_actions_person ON community_actions (person_id);
|
||||
|
||||
CREATE INDEX idx_community_actions_community ON community_actions (community_id);
|
||||
|
||||
CREATE INDEX idx_community_actions_followed ON community_actions (followed)
|
||||
WHERE
|
||||
followed IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_community_actions_followed_not_null ON community_actions (person_id, community_id)
|
||||
WHERE
|
||||
followed IS NOT NULL OR follow_state IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_community_actions_became_moderator ON community_actions (became_moderator)
|
||||
WHERE
|
||||
became_moderator IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_community_actions_became_moderator_not_null ON community_actions (person_id, community_id)
|
||||
WHERE
|
||||
became_moderator IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_community_actions_blocked_not_null ON community_actions (person_id, community_id)
|
||||
WHERE
|
||||
blocked IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_community_actions_received_ban_not_null ON community_actions (person_id, community_id)
|
||||
WHERE
|
||||
received_ban IS NOT NULL;
|
||||
|
||||
-- instance_actions
|
||||
CREATE TABLE instance_actions AS
|
||||
SELECT
|
||||
person_id,
|
||||
instance_id,
|
||||
published AS blocked
|
||||
FROM
|
||||
instance_block;
|
||||
|
||||
DROP TABLE instance_block;
|
||||
|
||||
-- Add the constraints
|
||||
ALTER TABLE instance_actions
|
||||
ALTER COLUMN person_id SET NOT NULL,
|
||||
ALTER COLUMN instance_id SET NOT NULL,
|
||||
ADD PRIMARY KEY (person_id, instance_id),
|
||||
ADD CONSTRAINT instance_actions_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT instance_actions_instance_id_fkey FOREIGN KEY (instance_id) REFERENCES instance ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
-- This index is currently redundant because instance_actions only has 1 action type, but inconsistency
|
||||
-- with other tables would make it harder to do everything correctly when adding another action type
|
||||
CREATE INDEX idx_instance_actions_person ON instance_actions (person_id);
|
||||
|
||||
CREATE INDEX idx_instance_actions_instance ON instance_actions (instance_id);
|
||||
|
||||
CREATE INDEX idx_instance_actions_blocked_not_null ON instance_actions (person_id, instance_id)
|
||||
WHERE
|
||||
blocked IS NOT NULL;
|
||||
|
||||
-- person_actions
|
||||
CREATE TABLE person_actions AS
|
||||
SELECT
|
||||
person_id,
|
||||
target_id,
|
||||
max(followed) AS followed,
|
||||
cast(max(follow_pending) AS boolean) AS follow_pending,
|
||||
max(blocked) AS blocked
|
||||
FROM (
|
||||
SELECT
|
||||
follower_id AS person_id,
|
||||
person_id AS target_id,
|
||||
published AS followed,
|
||||
pending::int AS follow_pending,
|
||||
NULL::timestamptz AS blocked
|
||||
FROM
|
||||
person_follower
|
||||
UNION ALL
|
||||
SELECT
|
||||
person_id,
|
||||
target_id,
|
||||
NULL::timestamptz,
|
||||
NULL::int,
|
||||
published
|
||||
FROM
|
||||
person_block)
|
||||
GROUP BY
|
||||
person_id,
|
||||
target_id;
|
||||
|
||||
-- add primary key, foreign keys, and not nulls
|
||||
ALTER TABLE person_actions
|
||||
ALTER COLUMN person_id SET NOT NULL,
|
||||
ALTER COLUMN target_id SET NOT NULL,
|
||||
ADD PRIMARY KEY (person_id, target_id),
|
||||
ADD CONSTRAINT person_actions_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_actions_target_id_fkey FOREIGN KEY (target_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_actions_check_followed CHECK (((followed IS NULL) = (follow_pending IS NULL)));
|
||||
|
||||
DROP TABLE person_block, person_follower;
|
||||
|
||||
CREATE INDEX idx_person_actions_person ON person_actions (person_id);
|
||||
|
||||
CREATE INDEX idx_person_actions_target ON person_actions (target_id);
|
||||
|
||||
CREATE INDEX idx_person_actions_followed_not_null ON person_actions (person_id, target_id)
|
||||
WHERE
|
||||
followed IS NOT NULL OR follow_pending IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_person_actions_blocked_not_null ON person_actions (person_id, target_id)
|
||||
WHERE
|
||||
blocked IS NOT NULL;
|
||||
|
||||
-- Create new statistics for more accurate estimations of how much of an index will be read (e.g. for
|
||||
-- `(liked, like_score)`, the query planner might othewise assume that `(TRUE, FALSE)` and `(TRUE, TRUE)`
|
||||
-- are equally likely when only `(TRUE, TRUE)` is possible, which would make it severely underestimate
|
||||
|
@ -424,51 +391,3 @@ FROM post_actions;
|
|||
CREATE statistics post_actions_liked_stat ON (liked IS NULL), (like_score IS NULL), (post_id IS NULL)
|
||||
FROM post_actions;
|
||||
|
||||
ALTER TABLE comment_actions
|
||||
ADD CONSTRAINT comment_actions_check_liked CHECK ((liked IS NULL) = (like_score IS NULL));
|
||||
|
||||
ALTER TABLE community_actions
|
||||
ADD CONSTRAINT community_actions_check_followed CHECK ((followed IS NULL) = (follow_state IS NULL) AND NOT (followed IS NULL AND follow_approver_id IS NOT NULL)),
|
||||
ADD CONSTRAINT community_actions_check_received_ban CHECK (NOT (received_ban IS NULL AND ban_expires IS NOT NULL));
|
||||
|
||||
ALTER TABLE person_actions
|
||||
ADD CONSTRAINT person_actions_check_followed CHECK ((followed IS NULL) = (follow_pending IS NULL));
|
||||
|
||||
ALTER TABLE post_actions
|
||||
ADD CONSTRAINT post_actions_check_read_comments CHECK ((read_comments IS NULL) = (read_comments_amount IS NULL)),
|
||||
ADD CONSTRAINT post_actions_check_liked CHECK ((liked IS NULL) = (like_score IS NULL));
|
||||
|
||||
-- Remove deferrable to restore original db schema
|
||||
ALTER TABLE community_actions
|
||||
ALTER CONSTRAINT community_actions_community_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE community_actions
|
||||
ALTER CONSTRAINT community_actions_follow_approver_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE community_actions
|
||||
ALTER CONSTRAINT community_actions_person_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE comment_actions
|
||||
ALTER CONSTRAINT comment_actions_comment_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE comment_actions
|
||||
ALTER CONSTRAINT comment_actions_person_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE instance_actions
|
||||
ALTER CONSTRAINT instance_actions_instance_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE instance_actions
|
||||
ALTER CONSTRAINT instance_actions_person_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE person_actions
|
||||
ALTER CONSTRAINT person_actions_person_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE person_actions
|
||||
ALTER CONSTRAINT person_actions_target_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE post_actions
|
||||
ALTER CONSTRAINT post_actions_person_id_fkey NOT DEFERRABLE;
|
||||
|
||||
ALTER TABLE post_actions
|
||||
ALTER CONSTRAINT post_actions_post_id_fkey NOT DEFERRABLE;
|
||||
|
||||
|
|
|
@ -4,9 +4,22 @@ ALTER TABLE post_aggregates
|
|||
ADD COLUMN report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE comment_aggregates
|
||||
ADD COLUMN report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0;
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE post_aggregates DISABLE TRIGGER ALL;
|
||||
|
||||
-- disable all table indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'post_aggregates');
|
||||
|
||||
-- Update the historical counts
|
||||
-- Posts
|
||||
|
@ -43,6 +56,47 @@ FROM (
|
|||
WHERE
|
||||
a.post_id = cnt.post_id;
|
||||
|
||||
-- Re-enable triggers after upserts
|
||||
ALTER TABLE post_aggregates ENABLE TRIGGER ALL;
|
||||
|
||||
-- Re-enable indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'post_aggregates');
|
||||
|
||||
-- reindex
|
||||
REINDEX TABLE post_aggregates;
|
||||
|
||||
ALTER TABLE comment_aggregates
|
||||
ADD COLUMN report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE comment_aggregates DISABLE TRIGGER ALL;
|
||||
|
||||
-- disable all table indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'comment_aggregates');
|
||||
|
||||
-- Comments
|
||||
UPDATE
|
||||
comment_aggregates AS a
|
||||
|
@ -77,3 +131,23 @@ FROM (
|
|||
WHERE
|
||||
a.comment_id = cnt.comment_id;
|
||||
|
||||
-- Re-enable triggers after upserts
|
||||
ALTER TABLE comment_aggregates ENABLE TRIGGER ALL;
|
||||
|
||||
-- Re-enable indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'comment_aggregates');
|
||||
|
||||
-- reindex
|
||||
REINDEX TABLE comment_aggregates;
|
||||
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
DROP TABLE person_content_combined;
|
||||
|
||||
DROP TABLE person_saved_combined;
|
||||
DROP TABLE person_content_combined, person_saved_combined;
|
||||
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
-- Creates combined tables for
|
||||
-- person_content: (comment, post)
|
||||
-- person_saved: (comment, post)
|
||||
CREATE TABLE person_content_combined (
|
||||
id serial PRIMARY KEY,
|
||||
published timestamptz NOT NULL,
|
||||
post_id int UNIQUE REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
comment_id int UNIQUE REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE
|
||||
);
|
||||
|
||||
CREATE INDEX idx_person_content_combined_published ON person_content_combined (published DESC, id DESC);
|
||||
|
||||
-- Updating the history
|
||||
INSERT INTO person_content_combined (published, post_id, comment_id)
|
||||
-- TODO I have a feeling not including person_id on this table is a mistake, the join might not be fast.
|
||||
CREATE TABLE person_content_combined AS
|
||||
SELECT
|
||||
published,
|
||||
id,
|
||||
NULL::int
|
||||
id AS post_id,
|
||||
NULL::int AS comment_id
|
||||
FROM
|
||||
post
|
||||
UNION ALL
|
||||
|
@ -26,51 +17,55 @@ SELECT
|
|||
FROM
|
||||
comment;
|
||||
|
||||
-- This one is special, because you use the saved date, not the ordinary published
|
||||
CREATE TABLE person_saved_combined (
|
||||
id serial PRIMARY KEY,
|
||||
saved timestamptz NOT NULL,
|
||||
person_id int NOT NULL REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE
|
||||
);
|
||||
-- Add the constraints
|
||||
ALTER TABLE person_content_combined
|
||||
ADD COLUMN id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
ALTER COLUMN published SET NOT NULL,
|
||||
ADD CONSTRAINT person_content_combined_post_id_fkey FOREIGN KEY (post_id) REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_content_combined_comment_id_fkey FOREIGN KEY (comment_id) REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD UNIQUE (post_id),
|
||||
ADD UNIQUE (comment_id),
|
||||
ADD CONSTRAINT person_content_combined_check CHECK (num_nonnulls (post_id, comment_id) = 1);
|
||||
|
||||
-- Updating the history
|
||||
INSERT INTO person_saved_combined (saved, person_id, post_id, comment_id)
|
||||
-- This is for local_users only
|
||||
CREATE TABLE person_saved_combined AS
|
||||
SELECT
|
||||
saved,
|
||||
person_id,
|
||||
post_id,
|
||||
NULL::int
|
||||
pa.saved AS saved,
|
||||
pa.person_id AS person_id,
|
||||
pa.post_id AS post_id,
|
||||
NULL::int AS comment_id
|
||||
FROM
|
||||
post_actions
|
||||
post_actions pa,
|
||||
local_user lu
|
||||
WHERE
|
||||
saved IS NOT NULL
|
||||
pa.person_id = lu.person_id
|
||||
AND pa.saved IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT
|
||||
saved,
|
||||
person_id,
|
||||
ca.saved,
|
||||
ca.person_id,
|
||||
NULL::int,
|
||||
comment_id
|
||||
ca.comment_id
|
||||
FROM
|
||||
comment_actions
|
||||
comment_actions ca,
|
||||
local_user lu
|
||||
WHERE
|
||||
saved IS NOT NULL;
|
||||
ca.person_id = lu.person_id
|
||||
AND ca.saved IS NOT NULL;
|
||||
|
||||
-- Add the constraints
|
||||
ALTER TABLE person_saved_combined
|
||||
ADD COLUMN id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
ALTER COLUMN saved SET NOT NULL,
|
||||
ALTER COLUMN person_id SET NOT NULL,
|
||||
ADD CONSTRAINT person_saved_combined_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_saved_combined_post_id_fkey FOREIGN KEY (post_id) REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_saved_combined_comment_id_fkey FOREIGN KEY (comment_id) REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_saved_combined_check CHECK (num_nonnulls (post_id, comment_id) = 1),
|
||||
ADD UNIQUE (person_id, post_id),
|
||||
ADD UNIQUE (person_id, comment_id);
|
||||
|
||||
CREATE INDEX idx_person_saved_combined_published ON person_saved_combined (saved DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_person_saved_combined ON person_saved_combined (person_id);
|
||||
|
||||
ALTER TABLE person_saved_combined
|
||||
ALTER CONSTRAINT person_saved_combined_person_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT person_saved_combined_post_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT person_saved_combined_comment_id_fkey NOT DEFERRABLE,
|
||||
ADD CONSTRAINT person_saved_combined_person_id_post_id_key UNIQUE (person_id, post_id),
|
||||
ADD CONSTRAINT person_saved_combined_person_id_comment_id_key UNIQUE (person_id, comment_id),
|
||||
ADD CONSTRAINT person_saved_combined_check CHECK (num_nonnulls (post_id, comment_id) = 1);
|
||||
|
||||
ALTER TABLE person_content_combined
|
||||
ALTER CONSTRAINT person_content_combined_post_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT person_content_combined_comment_id_fkey NOT DEFERRABLE,
|
||||
ADD CONSTRAINT person_content_combined_check CHECK (num_nonnulls (post_id, comment_id) = 1);
|
||||
|
||||
|
|
|
@ -6,30 +6,22 @@ ALTER TABLE person_mention RENAME TO person_comment_mention;
|
|||
|
||||
-- Create the new post_mention table
|
||||
CREATE TABLE person_post_mention (
|
||||
id serial PRIMARY KEY,
|
||||
recipient_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE NOT NULL,
|
||||
post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE NOT NULL,
|
||||
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
recipient_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
read boolean DEFAULT FALSE NOT NULL,
|
||||
published timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE inbox_combined (
|
||||
id serial PRIMARY KEY,
|
||||
published timestamptz NOT NULL,
|
||||
comment_reply_id int UNIQUE REFERENCES comment_reply ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
person_comment_mention_id int UNIQUE REFERENCES person_comment_mention ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
person_post_mention_id int UNIQUE REFERENCES person_post_mention ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
private_message_id int UNIQUE REFERENCES private_message ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE
|
||||
published timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (recipient_id, post_id)
|
||||
);
|
||||
|
||||
-- Updating the history
|
||||
INSERT INTO inbox_combined (published, comment_reply_id, person_comment_mention_id, person_post_mention_id, private_message_id)
|
||||
CREATE TABLE inbox_combined AS
|
||||
SELECT
|
||||
published,
|
||||
id,
|
||||
NULL::int,
|
||||
NULL::int,
|
||||
NULL::int
|
||||
id AS comment_reply_id,
|
||||
NULL::int AS person_comment_mention_id,
|
||||
NULL::int AS person_post_mention_id,
|
||||
NULL::int AS private_message_id
|
||||
FROM
|
||||
comment_reply
|
||||
UNION ALL
|
||||
|
@ -60,20 +52,20 @@ SELECT
|
|||
FROM
|
||||
private_message;
|
||||
|
||||
ALTER TABLE inbox_combined
|
||||
ADD COLUMN id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
ALTER COLUMN published SET NOT NULL,
|
||||
ADD CONSTRAINT inbox_combined_comment_reply_id_fkey FOREIGN KEY (comment_reply_id) REFERENCES comment_reply ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT inbox_combined_person_comment_mention_id_fkey FOREIGN KEY (person_comment_mention_id) REFERENCES person_comment_mention ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT inbox_combined_person_post_mention_id_fkey FOREIGN KEY (person_post_mention_id) REFERENCES person_post_mention ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT inbox_combined_private_message_id_fkey FOREIGN KEY (private_message_id) REFERENCES private_message ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD UNIQUE (comment_reply_id),
|
||||
ADD UNIQUE (person_comment_mention_id),
|
||||
ADD UNIQUE (person_post_mention_id),
|
||||
ADD UNIQUE (private_message_id),
|
||||
ADD CONSTRAINT inbox_combined_check CHECK (num_nonnulls (comment_reply_id, person_comment_mention_id, person_post_mention_id, private_message_id) = 1);
|
||||
|
||||
CREATE INDEX idx_inbox_combined_published ON inbox_combined (published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_inbox_combined_published_asc ON inbox_combined (reverse_timestamp_sort (published) DESC, id DESC);
|
||||
|
||||
ALTER TABLE person_post_mention
|
||||
ALTER CONSTRAINT person_post_mention_recipient_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT person_post_mention_post_id_fkey NOT DEFERRABLE,
|
||||
ADD CONSTRAINT person_post_mention_unique UNIQUE (recipient_id, post_id);
|
||||
|
||||
-- Make sure only one of the columns is not null
|
||||
ALTER TABLE inbox_combined
|
||||
ADD CONSTRAINT inbox_combined_check CHECK (num_nonnulls (comment_reply_id, person_comment_mention_id, person_post_mention_id, private_message_id) = 1),
|
||||
ALTER CONSTRAINT inbox_combined_comment_reply_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT inbox_combined_person_comment_mention_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT inbox_combined_person_post_mention_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT inbox_combined_private_message_id_fkey NOT DEFERRABLE;
|
||||
|
||||
|
|
|
@ -1,20 +1,5 @@
|
|||
-- Creates combined tables for
|
||||
-- Search: (post, comment, community, person)
|
||||
CREATE TABLE search_combined (
|
||||
id serial PRIMARY KEY,
|
||||
published timestamptz NOT NULL,
|
||||
-- This is used for the top sort
|
||||
-- For persons: its post score
|
||||
-- For comments: score,
|
||||
-- For posts: score,
|
||||
-- For community: users active monthly
|
||||
score bigint NOT NULL DEFAULT 0,
|
||||
post_id int UNIQUE REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
comment_id int UNIQUE REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
community_id int UNIQUE REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
person_id int UNIQUE REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE
|
||||
);
|
||||
|
||||
-- Add published to person_aggregates (it was missing for some reason)
|
||||
ALTER TABLE person_aggregates
|
||||
ADD COLUMN published timestamptz NOT NULL DEFAULT now();
|
||||
|
@ -28,21 +13,26 @@ FROM
|
|||
WHERE
|
||||
pa.person_id = p.id;
|
||||
|
||||
-- score is used for the top sort
|
||||
-- For persons: its post score
|
||||
-- For comments: score,
|
||||
-- For posts: score,
|
||||
-- For community: users active monthly
|
||||
-- Updating the history
|
||||
INSERT INTO search_combined (published, score, post_id, comment_id, community_id, person_id)
|
||||
CREATE TABLE search_combined AS
|
||||
SELECT
|
||||
published,
|
||||
score,
|
||||
score::int,
|
||||
post_id,
|
||||
NULL::int,
|
||||
NULL::int,
|
||||
NULL::int
|
||||
NULL::int AS comment_id,
|
||||
NULL::int AS community_id,
|
||||
NULL::int AS person_id
|
||||
FROM
|
||||
post_aggregates
|
||||
UNION ALL
|
||||
SELECT
|
||||
published,
|
||||
score,
|
||||
score::int,
|
||||
NULL::int,
|
||||
comment_id,
|
||||
NULL::int,
|
||||
|
@ -52,7 +42,7 @@ FROM
|
|||
UNION ALL
|
||||
SELECT
|
||||
published,
|
||||
users_active_month,
|
||||
users_active_month::int,
|
||||
NULL::int,
|
||||
NULL::int,
|
||||
community_id,
|
||||
|
@ -62,7 +52,7 @@ FROM
|
|||
UNION ALL
|
||||
SELECT
|
||||
published,
|
||||
post_score,
|
||||
post_score::int,
|
||||
NULL::int,
|
||||
NULL::int,
|
||||
NULL::int,
|
||||
|
@ -70,17 +60,25 @@ SELECT
|
|||
FROM
|
||||
person_aggregates;
|
||||
|
||||
-- Add the constraints
|
||||
ALTER TABLE search_combined
|
||||
ADD COLUMN id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
ALTER COLUMN published SET NOT NULL,
|
||||
ALTER COLUMN score SET NOT NULL,
|
||||
ALTER COLUMN score SET DEFAULT 0,
|
||||
ADD CONSTRAINT search_combined_post_id_fkey FOREIGN KEY (post_id) REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT search_combined_comment_id_fkey FOREIGN KEY (comment_id) REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT search_combined_community_id_fkey FOREIGN KEY (community_id) REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT search_combined_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD UNIQUE (post_id),
|
||||
ADD UNIQUE (comment_id),
|
||||
ADD UNIQUE (community_id),
|
||||
ADD UNIQUE (person_id),
|
||||
ADD CONSTRAINT search_combined_check CHECK (num_nonnulls (post_id, comment_id, community_id, person_id) = 1);
|
||||
|
||||
CREATE INDEX idx_search_combined_published ON search_combined (published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_search_combined_published_asc ON search_combined (reverse_timestamp_sort (published) DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_search_combined_score ON search_combined (score DESC, id DESC);
|
||||
|
||||
-- Make sure only one of the columns is not null
|
||||
ALTER TABLE search_combined
|
||||
ADD CONSTRAINT search_combined_check CHECK (num_nonnulls (post_id, comment_id, community_id, person_id) = 1),
|
||||
ALTER CONSTRAINT search_combined_post_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT search_combined_comment_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT search_combined_community_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT search_combined_person_id_fkey NOT DEFERRABLE;
|
||||
|
||||
|
|
|
@ -4,6 +4,39 @@
|
|||
-- Because of a postgres bug, you can't assign this to a new enum value,
|
||||
-- unless you run an unsafe commit first. So just use active.
|
||||
-- https://dba.stackexchange.com/questions/280371/postgres-unsafe-use-of-new-value-of-enum-type
|
||||
--
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE local_user DISABLE TRIGGER ALL;
|
||||
|
||||
ALTER TABLE local_site DISABLE TRIGGER ALL;
|
||||
|
||||
-- disable all table indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'local_user');
|
||||
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'local_site');
|
||||
|
||||
UPDATE
|
||||
local_user
|
||||
SET
|
||||
|
@ -67,3 +100,40 @@ ALTER TABLE local_user
|
|||
ALTER TABLE local_site
|
||||
ADD COLUMN default_post_time_range_seconds integer;
|
||||
|
||||
-- Re-enable the triggers
|
||||
ALTER TABLE local_user ENABLE TRIGGER ALL;
|
||||
|
||||
ALTER TABLE local_site ENABLE TRIGGER ALL;
|
||||
|
||||
-- re-enable indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'local_user');
|
||||
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'local_site');
|
||||
|
||||
-- reindex
|
||||
REINDEX TABLE local_user;
|
||||
|
||||
REINDEX TABLE local_site;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
-- move comment_aggregates back into separate table
|
||||
CREATE TABLE comment_aggregates (
|
||||
comment_id int PRIMARY KEY NOT NULL REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
CREATE TABLE IF NOT EXISTS comment_aggregates (
|
||||
comment_id int PRIMARY KEY NOT NULL REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
score bigint NOT NULL DEFAULT 0,
|
||||
upvotes bigint NOT NULL DEFAULT 0,
|
||||
downvotes bigint NOT NULL DEFAULT 0,
|
||||
|
@ -25,7 +25,18 @@ SELECT
|
|||
report_count,
|
||||
unresolved_report_count
|
||||
FROM
|
||||
comment;
|
||||
COMMENT
|
||||
ON CONFLICT (comment_id)
|
||||
DO UPDATE SET
|
||||
score = excluded.score,
|
||||
upvotes = excluded.upvotes,
|
||||
downvotes = excluded.downvotes,
|
||||
published = excluded.published,
|
||||
child_count = excluded.child_count,
|
||||
hot_rank = excluded.hot_rank,
|
||||
controversy_rank = excluded.controversy_rank,
|
||||
report_count = excluded.report_count,
|
||||
unresolved_report_count = excluded.unresolved_report_count;
|
||||
|
||||
ALTER TABLE comment
|
||||
DROP COLUMN score,
|
||||
|
@ -37,24 +48,23 @@ ALTER TABLE comment
|
|||
DROP COLUMN report_count,
|
||||
DROP COLUMN unresolved_report_count;
|
||||
|
||||
SET CONSTRAINTS comment_aggregates_comment_id_fkey IMMEDIATE;
|
||||
ALTER TABLE comment_aggregates
|
||||
ALTER CONSTRAINT comment_aggregates_comment_id_fkey DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
SET CONSTRAINTS comment_aggregates_comment_id_fkey DEFERRED;
|
||||
CREATE INDEX IF NOT EXISTS idx_comment_aggregates_controversy ON comment_aggregates USING btree (controversy_rank DESC);
|
||||
|
||||
CREATE INDEX idx_comment_aggregates_controversy ON comment_aggregates USING btree (controversy_rank DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_comment_aggregates_hot ON comment_aggregates USING btree (hot_rank DESC, score DESC);
|
||||
|
||||
CREATE INDEX idx_comment_aggregates_hot ON comment_aggregates USING btree (hot_rank DESC, score DESC);
|
||||
|
||||
CREATE INDEX idx_comment_aggregates_nonzero_hotrank ON comment_aggregates USING btree (published)
|
||||
CREATE INDEX IF NOT EXISTS idx_comment_aggregates_nonzero_hotrank ON comment_aggregates USING btree (published)
|
||||
WHERE (hot_rank <> (0)::double precision);
|
||||
|
||||
CREATE INDEX idx_comment_aggregates_published ON comment_aggregates USING btree (published DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_comment_aggregates_published ON comment_aggregates USING btree (published DESC);
|
||||
|
||||
CREATE INDEX idx_comment_aggregates_score ON comment_aggregates USING btree (score DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_comment_aggregates_score ON comment_aggregates USING btree (score DESC);
|
||||
|
||||
-- move comment_aggregates back into separate table
|
||||
CREATE TABLE post_aggregates (
|
||||
post_id int PRIMARY KEY NOT NULL REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
CREATE TABLE IF NOT EXISTS post_aggregates (
|
||||
post_id int PRIMARY KEY NOT NULL REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
comments bigint NOT NULL DEFAULT 0,
|
||||
score bigint NOT NULL DEFAULT 0,
|
||||
upvotes bigint NOT NULL DEFAULT 0,
|
||||
|
@ -66,10 +76,10 @@ CREATE TABLE post_aggregates (
|
|||
featured_local boolean NOT NULL DEFAULT FALSE,
|
||||
hot_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
hot_rank_active double precision NOT NULL DEFAULT 0.0001,
|
||||
community_id integer NOT NULL REFERENCES community (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
creator_id integer NOT NULL REFERENCES person (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
community_id integer NOT NULL REFERENCES community (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
creator_id integer NOT NULL REFERENCES person (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
controversy_rank double precision NOT NULL DEFAULT 0,
|
||||
instance_id integer NOT NULL REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
instance_id integer NOT NULL REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
scaled_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
report_count smallint NOT NULL DEFAULT 0,
|
||||
unresolved_report_count smallint NOT NULL DEFAULT 0
|
||||
|
@ -97,7 +107,27 @@ SELECT
|
|||
report_count,
|
||||
unresolved_report_count
|
||||
FROM
|
||||
post;
|
||||
post
|
||||
ON CONFLICT (post_id)
|
||||
DO UPDATE SET
|
||||
comments = excluded.comments,
|
||||
score = excluded.score,
|
||||
upvotes = excluded.upvotes,
|
||||
downvotes = excluded.downvotes,
|
||||
published = excluded.published,
|
||||
newest_comment_time_necro = excluded.newest_comment_time_necro,
|
||||
newest_comment_time = excluded.newest_comment_time,
|
||||
featured_community = excluded.featured_community,
|
||||
featured_local = excluded.featured_local,
|
||||
hot_rank = excluded.hot_rank,
|
||||
hot_rank_active = excluded.hot_rank_active,
|
||||
community_id = excluded.community_id,
|
||||
creator_id = excluded.creator_id,
|
||||
controversy_rank = excluded.controversy_rank,
|
||||
instance_id = excluded.instance_id,
|
||||
scaled_rank = excluded.scaled_rank,
|
||||
report_count = excluded.report_count,
|
||||
unresolved_report_count = excluded.unresolved_report_count;
|
||||
|
||||
ALTER TABLE post
|
||||
DROP COLUMN comments,
|
||||
|
@ -114,76 +144,78 @@ ALTER TABLE post
|
|||
DROP COLUMN report_count,
|
||||
DROP COLUMN unresolved_report_count;
|
||||
|
||||
SET CONSTRAINTS post_aggregates_community_id_fkey, post_aggregates_creator_id_fkey, post_aggregates_instance_id_fkey, post_aggregates_post_id_fkey IMMEDIATE;
|
||||
ALTER TABLE post_aggregates
|
||||
ALTER CONSTRAINT post_aggregates_community_id_fkey DEFERRABLE INITIALLY DEFERRED,
|
||||
ALTER CONSTRAINT post_aggregates_creator_id_fkey DEFERRABLE INITIALLY DEFERRED,
|
||||
ALTER CONSTRAINT post_aggregates_instance_id_fkey DEFERRABLE INITIALLY DEFERRED,
|
||||
ALTER CONSTRAINT post_aggregates_post_id_fkey DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
SET CONSTRAINTS post_aggregates_community_id_fkey, post_aggregates_creator_id_fkey, post_aggregates_instance_id_fkey, post_aggregates_post_id_fkey DEFERRED;
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_active ON post_aggregates USING btree (community_id, featured_local DESC, hot_rank_active DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_active ON post_aggregates USING btree (community_id, featured_local DESC, hot_rank_active DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_controversy ON post_aggregates USING btree (community_id, featured_local DESC, controversy_rank DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_controversy ON post_aggregates USING btree (community_id, featured_local DESC, controversy_rank DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_hot ON post_aggregates USING btree (community_id, featured_local DESC, hot_rank DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_hot ON post_aggregates USING btree (community_id, featured_local DESC, hot_rank DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_most_comments ON post_aggregates USING btree (community_id, featured_local DESC, comments DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_most_comments ON post_aggregates USING btree (community_id, featured_local DESC, comments DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_newest_comment_time ON post_aggregates USING btree (community_id, featured_local DESC, newest_comment_time DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_newest_comment_time ON post_aggregates USING btree (community_id, featured_local DESC, newest_comment_time DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_newest_comment_time_necro ON post_aggregates USING btree (community_id, featured_local DESC, newest_comment_time_necro DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_newest_comment_time_necro ON post_aggregates USING btree (community_id, featured_local DESC, newest_comment_time_necro DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_published ON post_aggregates USING btree (community_id, featured_local DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_published ON post_aggregates USING btree (community_id, featured_local DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_published_asc ON post_aggregates USING btree (community_id, featured_local DESC, reverse_timestamp_sort (published) DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_published_asc ON post_aggregates USING btree (community_id, featured_local DESC, reverse_timestamp_sort (published) DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_scaled ON post_aggregates USING btree (community_id, featured_local DESC, scaled_rank DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_scaled ON post_aggregates USING btree (community_id, featured_local DESC, scaled_rank DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_community_score ON post_aggregates USING btree (community_id, featured_local DESC, score DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_community_score ON post_aggregates USING btree (community_id, featured_local DESC, score DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_active ON post_aggregates USING btree (community_id, featured_community DESC, hot_rank_active DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_active ON post_aggregates USING btree (community_id, featured_community DESC, hot_rank_active DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_controversy ON post_aggregates USING btree (community_id, featured_community DESC, controversy_rank DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_controversy ON post_aggregates USING btree (community_id, featured_community DESC, controversy_rank DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_hot ON post_aggregates USING btree (community_id, featured_community DESC, hot_rank DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_hot ON post_aggregates USING btree (community_id, featured_community DESC, hot_rank DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_most_comments ON post_aggregates USING btree (community_id, featured_community DESC, comments DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_most_comments ON post_aggregates USING btree (community_id, featured_community DESC, comments DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_newest_comment_time ON post_aggregates USING btree (community_id, featured_community DESC, newest_comment_time DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_newest_comment_time ON post_aggregates USING btree (community_id, featured_community DESC, newest_comment_time DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_newest_comment_time_necr ON post_aggregates USING btree (community_id, featured_community DESC, newest_comment_time_necro DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_newest_comment_time_necr ON post_aggregates USING btree (community_id, featured_community DESC, newest_comment_time_necro DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_published ON post_aggregates USING btree (community_id, featured_community DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_published ON post_aggregates USING btree (community_id, featured_community DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_published_asc ON post_aggregates USING btree (community_id, featured_community DESC, reverse_timestamp_sort (published) DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_published_asc ON post_aggregates USING btree (community_id, featured_community DESC, reverse_timestamp_sort (published) DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_scaled ON post_aggregates USING btree (community_id, featured_community DESC, scaled_rank DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_scaled ON post_aggregates USING btree (community_id, featured_community DESC, scaled_rank DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_community_score ON post_aggregates USING btree (community_id, featured_community DESC, score DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_community_score ON post_aggregates USING btree (community_id, featured_community DESC, score DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_active ON post_aggregates USING btree (featured_local DESC, hot_rank_active DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_active ON post_aggregates USING btree (featured_local DESC, hot_rank_active DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_controversy ON post_aggregates USING btree (featured_local DESC, controversy_rank DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_controversy ON post_aggregates USING btree (featured_local DESC, controversy_rank DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_hot ON post_aggregates USING btree (featured_local DESC, hot_rank DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_hot ON post_aggregates USING btree (featured_local DESC, hot_rank DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_most_comments ON post_aggregates USING btree (featured_local DESC, comments DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_most_comments ON post_aggregates USING btree (featured_local DESC, comments DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_newest_comment_time ON post_aggregates USING btree (featured_local DESC, newest_comment_time DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_newest_comment_time ON post_aggregates USING btree (featured_local DESC, newest_comment_time DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_newest_comment_time_necro ON post_aggregates USING btree (featured_local DESC, newest_comment_time_necro DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_newest_comment_time_necro ON post_aggregates USING btree (featured_local DESC, newest_comment_time_necro DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_published ON post_aggregates USING btree (featured_local DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_published ON post_aggregates USING btree (featured_local DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_published_asc ON post_aggregates USING btree (featured_local DESC, reverse_timestamp_sort (published) DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_published_asc ON post_aggregates USING btree (featured_local DESC, reverse_timestamp_sort (published) DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_scaled ON post_aggregates USING btree (featured_local DESC, scaled_rank DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_scaled ON post_aggregates USING btree (featured_local DESC, scaled_rank DESC, published DESC, post_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_featured_local_score ON post_aggregates USING btree (featured_local DESC, score DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_featured_local_score ON post_aggregates USING btree (featured_local DESC, score DESC, published DESC, post_id DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_nonzero_hotrank ON post_aggregates USING btree (published DESC)
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_nonzero_hotrank ON post_aggregates USING btree (published DESC)
|
||||
WHERE ((hot_rank <> (0)::double precision) OR (hot_rank_active <> (0)::double precision));
|
||||
|
||||
CREATE INDEX idx_post_aggregates_published ON post_aggregates USING btree (published DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_published ON post_aggregates USING btree (published DESC);
|
||||
|
||||
CREATE INDEX idx_post_aggregates_published_asc ON post_aggregates USING btree (reverse_timestamp_sort (published) DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_aggregates_published_asc ON post_aggregates USING btree (reverse_timestamp_sort (published) DESC);
|
||||
|
||||
DROP INDEX idx_post_featured_community_published_asc;
|
||||
|
||||
|
@ -199,7 +231,7 @@ DROP INDEX idx_search_combined_score;
|
|||
|
||||
-- move community_aggregates back into separate table
|
||||
CREATE TABLE community_aggregates (
|
||||
community_id int PRIMARY KEY NOT NULL REFERENCES COMMunity ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
community_id int PRIMARY KEY NOT NULL REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
subscribers bigint NOT NULL DEFAULT 0,
|
||||
posts bigint NOT NULL DEFAULT 0,
|
||||
comments bigint NOT NULL DEFAULT 0,
|
||||
|
@ -246,12 +278,10 @@ ALTER TABLE community
|
|||
DROP COLUMN subscribers_local,
|
||||
DROP COLUMN report_count,
|
||||
DROP COLUMN unresolved_report_count,
|
||||
DROP COLUMN interactions_month,
|
||||
ALTER CONSTRAINT community_instance_id_fkey NOT DEFERRABLE INITIALLY IMMEDIATE;
|
||||
DROP COLUMN interactions_month;
|
||||
|
||||
SET CONSTRAINTS community_aggregates_community_id_fkey IMMEDIATE;
|
||||
|
||||
SET CONSTRAINTS community_aggregates_community_id_fkey DEFERRED;
|
||||
ALTER TABLE community
|
||||
ALTER CONSTRAINT community_instance_id_fkey NOT DEFERRABLE;
|
||||
|
||||
CREATE INDEX idx_community_aggregates_hot ON public.community_aggregates USING btree (hot_rank DESC);
|
||||
|
||||
|
@ -266,7 +296,7 @@ CREATE INDEX idx_community_aggregates_users_active_month ON public.community_agg
|
|||
|
||||
-- move person_aggregates back into separate table
|
||||
CREATE TABLE person_aggregates (
|
||||
person_id int PRIMARY KEY NOT NULL REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
person_id int PRIMARY KEY NOT NULL REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
post_count bigint NOT NULL DEFAULT 0,
|
||||
post_score bigint NOT NULL DEFAULT 0,
|
||||
comment_count bigint NOT NULL DEFAULT 0,
|
||||
|
@ -291,9 +321,8 @@ ALTER TABLE person
|
|||
DROP COLUMN comment_count,
|
||||
DROP COLUMN comment_score;
|
||||
|
||||
SET CONSTRAINTS person_aggregates_person_id_fkey IMMEDIATE;
|
||||
|
||||
SET CONSTRAINTS person_aggregates_person_id_fkey DEFERRED;
|
||||
ALTER TABLE person_aggregates
|
||||
ALTER CONSTRAINT person_aggregates_person_id_fkey DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
CREATE INDEX idx_person_aggregates_comment_score ON public.person_aggregates USING btree (comment_score DESC);
|
||||
|
||||
|
@ -301,7 +330,7 @@ CREATE INDEX idx_person_aggregates_person ON public.person_aggregates USING btre
|
|||
|
||||
-- move site_aggregates back into separate table
|
||||
CREATE TABLE site_aggregates (
|
||||
site_id int PRIMARY KEY NOT NULL REFERENCES site ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
site_id int PRIMARY KEY NOT NULL REFERENCES site ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
users bigint NOT NULL DEFAULT 1,
|
||||
posts bigint NOT NULL DEFAULT 0,
|
||||
comments bigint NOT NULL DEFAULT 0,
|
||||
|
@ -363,9 +392,11 @@ ALTER TABLE local_user
|
|||
|
||||
CREATE INDEX idx_search_combined_score ON public.search_combined USING btree (score DESC, id DESC);
|
||||
|
||||
SET CONSTRAINTS site_aggregates_site_id_fkey IMMEDIATE;
|
||||
|
||||
SET CONSTRAINTS site_aggregates_site_id_fkey DEFERRED;
|
||||
ALTER TABLE site_aggregates
|
||||
ALTER CONSTRAINT site_aggregates_site_id_fkey DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
CREATE UNIQUE INDEX idx_site_aggregates_1_row_only ON public.site_aggregates USING btree ((TRUE));
|
||||
|
||||
ALTER TABLE community_aggregates
|
||||
ALTER CONSTRAINT community_aggregates_community_id_fkey DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
|
|
|
@ -1,14 +1,31 @@
|
|||
-- merge comment_aggregates into comment table
|
||||
-- Merge comment_aggregates into comment table
|
||||
ALTER TABLE comment
|
||||
ADD COLUMN score bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN upvotes bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN downvotes bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN child_count integer NOT NULL DEFAULT 0,
|
||||
ADD COLUMN score int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN upvotes int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN downvotes int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN child_count int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN hot_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN controversy_rank double precision NOT NULL DEFAULT 0,
|
||||
ADD COLUMN report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE comment DISABLE TRIGGER ALL;
|
||||
|
||||
-- disable all table indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'comment');
|
||||
|
||||
UPDATE
|
||||
comment
|
||||
SET
|
||||
|
@ -25,6 +42,29 @@ FROM
|
|||
WHERE
|
||||
comment.id = ca.comment_id;
|
||||
|
||||
DROP TABLE comment_aggregates;
|
||||
|
||||
-- Re-enable triggers after upserts
|
||||
ALTER TABLE comment ENABLE TRIGGER ALL;
|
||||
|
||||
-- Re-enable indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'comment');
|
||||
|
||||
-- reindex
|
||||
REINDEX TABLE comment;
|
||||
|
||||
-- 30s-2m each
|
||||
CREATE INDEX idx_comment_controversy ON comment USING btree (controversy_rank DESC);
|
||||
|
||||
CREATE INDEX idx_comment_hot ON comment USING btree (hot_rank DESC, score DESC);
|
||||
|
@ -37,20 +77,37 @@ CREATE INDEX idx_comment_score ON comment USING btree (score DESC);
|
|||
|
||||
-- merge post_aggregates into post table
|
||||
ALTER TABLE post
|
||||
ADD COLUMN comments bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN score bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN upvotes bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN downvotes bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN score int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN upvotes int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN downvotes int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN newest_comment_time_necro timestamp with time zone NOT NULL DEFAULT now(),
|
||||
ADD COLUMN newest_comment_time timestamp with time zone NOT NULL DEFAULT now(),
|
||||
ADD COLUMN hot_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN hot_rank_active double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN controversy_rank double precision NOT NULL DEFAULT 0,
|
||||
ADD COLUMN instance_id int REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
ADD COLUMN instance_id int REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD COLUMN scaled_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE post DISABLE TRIGGER ALL;
|
||||
|
||||
-- disable all table indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'post');
|
||||
|
||||
UPDATE
|
||||
post
|
||||
SET
|
||||
|
@ -72,9 +129,28 @@ FROM
|
|||
WHERE
|
||||
post.id = pa.post_id;
|
||||
|
||||
ALTER TABLE post
|
||||
ALTER COLUMN instance_id SET NOT NULL,
|
||||
ALTER CONSTRAINT post_instance_id_fkey NOT DEFERRABLE;
|
||||
-- Delete that data
|
||||
DROP TABLE post_aggregates;
|
||||
|
||||
-- Re-enable triggers after upserts
|
||||
ALTER TABLE post ENABLE TRIGGER ALL;
|
||||
|
||||
-- Re-enable indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'post');
|
||||
|
||||
-- reindex
|
||||
REINDEX TABLE post;
|
||||
|
||||
CREATE INDEX idx_post_community_active ON post USING btree (community_id, featured_local DESC, hot_rank_active DESC, published DESC, id DESC);
|
||||
|
||||
|
@ -142,19 +218,35 @@ CREATE INDEX idx_post_published_asc ON post USING btree (reverse_timestamp_sort
|
|||
|
||||
-- merge community_aggregates into community table
|
||||
ALTER TABLE community
|
||||
ADD COLUMN subscribers bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN posts bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_day bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_week bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_month bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_half_year bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN subscribers int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN posts int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_day int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_week int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_month int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_half_year int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN hot_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN subscribers_local bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN subscribers_local int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN interactions_month bigint NOT NULL DEFAULT 0,
|
||||
ALTER CONSTRAINT community_instance_id_fkey DEFERRABLE INITIALLY DEFERRED;
|
||||
ADD COLUMN interactions_month int NOT NULL DEFAULT 0;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE community DISABLE TRIGGER ALL;
|
||||
|
||||
-- disable all table indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'community');
|
||||
|
||||
UPDATE
|
||||
community
|
||||
|
@ -176,6 +268,28 @@ FROM
|
|||
WHERE
|
||||
community.id = ca.community_id;
|
||||
|
||||
DROP TABLE community_aggregates;
|
||||
|
||||
-- Re-enable triggers after upserts
|
||||
ALTER TABLE community ENABLE TRIGGER ALL;
|
||||
|
||||
-- Re-enable indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'community');
|
||||
|
||||
-- reindex
|
||||
REINDEX TABLE community;
|
||||
|
||||
CREATE INDEX idx_community_hot ON public.community USING btree (hot_rank DESC);
|
||||
|
||||
CREATE INDEX idx_community_nonzero_hotrank ON public.community USING btree (published)
|
||||
|
@ -187,10 +301,27 @@ CREATE INDEX idx_community_users_active_month ON public.community USING btree (u
|
|||
|
||||
-- merge person_aggregates into person table
|
||||
ALTER TABLE person
|
||||
ADD COLUMN post_count bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN post_score bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comment_count bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comment_score bigint NOT NULL DEFAULT 0;
|
||||
ADD COLUMN post_count int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN post_score int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comment_count int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comment_score int NOT NULL DEFAULT 0;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE person DISABLE TRIGGER ALL;
|
||||
|
||||
-- disable all table indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'person');
|
||||
|
||||
UPDATE
|
||||
person
|
||||
|
@ -204,16 +335,55 @@ FROM
|
|||
WHERE
|
||||
person.id = pa.person_id;
|
||||
|
||||
-- merge site_aggregates into person table
|
||||
DROP TABLE person_aggregates;
|
||||
|
||||
-- Re-enable triggers after upserts
|
||||
ALTER TABLE person ENABLE TRIGGER ALL;
|
||||
|
||||
-- Re-enable indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'person');
|
||||
|
||||
-- reindex
|
||||
REINDEX TABLE person;
|
||||
|
||||
-- merge site_aggregates into local_site table
|
||||
ALTER TABLE local_site
|
||||
ADD COLUMN users bigint NOT NULL DEFAULT 1,
|
||||
ADD COLUMN posts bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN communities bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_day bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_week bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_month bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_half_year bigint NOT NULL DEFAULT 0;
|
||||
ADD COLUMN users int NOT NULL DEFAULT 1,
|
||||
ADD COLUMN posts int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN communities int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_day int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_week int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_month int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_half_year int NOT NULL DEFAULT 0;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE local_site DISABLE TRIGGER ALL;
|
||||
|
||||
-- disable all table indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'local_site');
|
||||
|
||||
UPDATE
|
||||
local_site
|
||||
|
@ -231,6 +401,28 @@ FROM
|
|||
WHERE
|
||||
local_site.site_id = sa.site_id;
|
||||
|
||||
DROP TABLE site_aggregates;
|
||||
|
||||
-- Re-enable triggers after upserts
|
||||
ALTER TABLE local_site ENABLE TRIGGER ALL;
|
||||
|
||||
-- Re-enable indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'local_site');
|
||||
|
||||
-- reindex
|
||||
REINDEX TABLE local_site;
|
||||
|
||||
-- merge local_user_vote_display_mode into local_user table
|
||||
ALTER TABLE local_user
|
||||
ADD COLUMN show_score boolean NOT NULL DEFAULT FALSE,
|
||||
|
@ -238,6 +430,23 @@ ALTER TABLE local_user
|
|||
ADD COLUMN show_downvotes boolean NOT NULL DEFAULT TRUE,
|
||||
ADD COLUMN show_upvote_percentage boolean NOT NULL DEFAULT FALSE;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE local_user DISABLE TRIGGER ALL;
|
||||
|
||||
-- disable all table indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = FALSE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'local_user');
|
||||
|
||||
UPDATE
|
||||
local_user
|
||||
SET
|
||||
|
@ -250,5 +459,25 @@ FROM
|
|||
WHERE
|
||||
local_user.id = v.local_user_id;
|
||||
|
||||
DROP TABLE comment_aggregates, post_aggregates, community_aggregates, person_aggregates, site_aggregates, local_user_vote_display_mode;
|
||||
DROP TABLE local_user_vote_display_mode;
|
||||
|
||||
-- Re-enable triggers after upserts
|
||||
ALTER TABLE local_user ENABLE TRIGGER ALL;
|
||||
|
||||
-- Re-enable indexes
|
||||
UPDATE
|
||||
pg_index
|
||||
SET
|
||||
indisready = TRUE
|
||||
WHERE
|
||||
indrelid = (
|
||||
SELECT
|
||||
oid
|
||||
FROM
|
||||
pg_class
|
||||
WHERE
|
||||
relname = 'local_user');
|
||||
|
||||
-- reindex
|
||||
REINDEX TABLE local_user;
|
||||
|
||||
|
|
|
@ -8,18 +8,18 @@ ALTER TABLE community
|
|||
ADD COLUMN visibility_new community_visibility NOT NULL DEFAULT 'Public',
|
||||
ADD COLUMN description_new varchar(150),
|
||||
ADD COLUMN random_number_new smallint NOT NULL DEFAULT random_smallint (),
|
||||
ADD COLUMN subscribers_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN posts_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_day_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_week_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_month_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_half_year_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN subscribers_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN posts_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_day_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_week_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_month_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_half_year_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN hot_rank_new double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN subscribers_local_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN subscribers_local_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN report_count_new smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count_new smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN interactions_month_new bigint NOT NULL DEFAULT 0;
|
||||
ADD COLUMN interactions_month_new int NOT NULL DEFAULT 0;
|
||||
|
||||
UPDATE
|
||||
community
|
||||
|
@ -62,10 +62,6 @@ SET
|
|||
unresolved_report_count,
|
||||
interactions_month);
|
||||
|
||||
SET CONSTRAINTS community_instance_id_fkey IMMEDIATE;
|
||||
|
||||
SET CONSTRAINTS community_instance_id_fkey DEFERRED;
|
||||
|
||||
ALTER TABLE community
|
||||
ALTER COLUMN instance_id_new SET NOT NULL,
|
||||
DROP COLUMN posting_restricted_to_mods,
|
||||
|
@ -129,7 +125,7 @@ ALTER TABLE community RENAME COLUMN interactions_month_new TO interactions_month
|
|||
ALTER TABLE community
|
||||
ADD CONSTRAINT community_featured_url_key UNIQUE (featured_url),
|
||||
ADD CONSTRAINT community_moderators_url_key UNIQUE (moderators_url),
|
||||
ADD CONSTRAINT community_instance_id_fkey FOREIGN KEY (instance_id) REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
|
||||
ADD CONSTRAINT community_instance_id_fkey FOREIGN KEY (instance_id) REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
-- same changes as up.sql, but the other way round
|
||||
UPDATE
|
||||
|
|
|
@ -18,10 +18,10 @@ ALTER TABLE person
|
|||
ADD COLUMN bot_account_new boolean DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN ban_expires timestamptz,
|
||||
ADD COLUMN instance_id_new int,
|
||||
ADD COLUMN post_count_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN post_score_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN comment_count_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN comment_score_new bigint DEFAULT 0 NOT NULL;
|
||||
ADD COLUMN post_count_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN post_score_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN comment_count_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN comment_score_new int DEFAULT 0 NOT NULL;
|
||||
|
||||
UPDATE
|
||||
person
|
||||
|
|
|
@ -22,10 +22,10 @@ ALTER TABLE post
|
|||
ADD COLUMN url_content_type_new text,
|
||||
ADD COLUMN alt_text_new text,
|
||||
ADD COLUMN scheduled_publish_time_new timestamp with time zone,
|
||||
ADD COLUMN comments_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN score_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN upvotes_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN downvotes_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN comments_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN score_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN upvotes_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN downvotes_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN newest_comment_time_necro_new timestamp with time zone DEFAULT now() NOT NULL,
|
||||
ADD COLUMN newest_comment_time_new timestamp with time zone DEFAULT now() NOT NULL,
|
||||
ADD COLUMN hot_rank_new double precision DEFAULT 0.0001 NOT NULL,
|
||||
|
@ -337,6 +337,3 @@ ALTER TABLE post
|
|||
ALTER TABLE post
|
||||
ALTER COLUMN ap_id SET NOT NULL;
|
||||
|
||||
ALTER TABLE post
|
||||
ALTER COLUMN instance_id SET NOT NULL;
|
||||
|
||||
|
|
|
@ -1,28 +1,14 @@
|
|||
-- Creates combined tables for
|
||||
-- person_liked: (comment, post)
|
||||
--
|
||||
-- This one is special, because you use the liked date, not the ordinary published
|
||||
CREATE TABLE person_liked_combined (
|
||||
id serial PRIMARY KEY,
|
||||
liked timestamptz NOT NULL,
|
||||
like_score smallint NOT NULL,
|
||||
person_id int NOT NULL REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE,
|
||||
comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE
|
||||
);
|
||||
|
||||
CREATE INDEX idx_person_liked_combined_published ON person_liked_combined (liked DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_person_liked_combined ON person_liked_combined (person_id);
|
||||
|
||||
-- Updating the history
|
||||
INSERT INTO person_liked_combined (liked, like_score, person_id, post_id, comment_id)
|
||||
CREATE TABLE person_liked_combined AS
|
||||
SELECT
|
||||
pa.liked,
|
||||
pa.like_score,
|
||||
pa.person_id,
|
||||
pa.post_id,
|
||||
NULL::int
|
||||
NULL::int AS comment_id
|
||||
FROM
|
||||
post_actions pa
|
||||
INNER JOIN person p ON pa.person_id = p.id
|
||||
|
@ -43,12 +29,17 @@ WHERE
|
|||
liked IS NOT NULL
|
||||
AND p.local = TRUE;
|
||||
|
||||
-- Make sure only one of the columns is not null
|
||||
ALTER TABLE person_liked_combined
|
||||
ADD CONSTRAINT person_liked_combined_person_id_comment_id_key UNIQUE (person_id, comment_id),
|
||||
ADD CONSTRAINT person_liked_combined_person_id_post_id_key UNIQUE (person_id, post_id),
|
||||
ADD CONSTRAINT person_liked_combined_check CHECK (num_nonnulls (post_id, comment_id) = 1),
|
||||
ALTER CONSTRAINT person_liked_combined_person_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT person_liked_combined_post_id_fkey NOT DEFERRABLE,
|
||||
ALTER CONSTRAINT person_liked_combined_comment_id_fkey NOT DEFERRABLE;
|
||||
ADD COLUMN id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
ALTER COLUMN liked SET NOT NULL,
|
||||
ALTER COLUMN like_score SET NOT NULL,
|
||||
ALTER COLUMN person_id SET NOT NULL,
|
||||
ADD CONSTRAINT person_liked_combined_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_liked_combined_post_id_fkey FOREIGN KEY (post_id) REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_liked_combined_comment_id_fkey FOREIGN KEY (comment_id) REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD UNIQUE (person_id, post_id),
|
||||
ADD UNIQUE (person_id, comment_id),
|
||||
ADD CONSTRAINT person_liked_combined_check CHECK (num_nonnulls (post_id, comment_id) = 1);
|
||||
|
||||
CREATE INDEX idx_person_liked_combined ON person_liked_combined (person_id);
|
||||
|
||||
|
|
|
@ -27,14 +27,14 @@ ALTER TABLE local_site
|
|||
ADD COLUMN comment_downvotes_new public.federation_mode_enum DEFAULT 'All'::public.federation_mode_enum NOT NULL,
|
||||
ADD COLUMN default_post_time_range_seconds_new integer,
|
||||
ADD COLUMN disallow_nsfw_content_new boolean DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN users_new bigint DEFAULT 1 NOT NULL,
|
||||
ADD COLUMN posts_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN comments_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN communities_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN users_active_day_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN users_active_week_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN users_active_month_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN users_active_half_year_new bigint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN users_new int DEFAULT 1 NOT NULL,
|
||||
ADD COLUMN posts_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN comments_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN communities_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN users_active_day_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN users_active_week_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN users_active_month_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN users_active_half_year_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN disable_email_notifications_new boolean DEFAULT FALSE NOT NULL;
|
||||
|
||||
-- Update
|
||||
|
|
|
@ -6,6 +6,9 @@ ALTER TABLE person_actions
|
|||
ALTER TABLE local_user
|
||||
ADD COLUMN show_person_votes boolean NOT NULL DEFAULT TRUE;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE person_actions DISABLE TRIGGER ALL;
|
||||
|
||||
-- Adding vote history
|
||||
-- This union alls the comment and post actions tables,
|
||||
-- inner joins to local_user for the above to filter out non-locals
|
||||
|
@ -47,3 +50,6 @@ ON CONFLICT (person_id,
|
|||
upvotes = excluded.upvotes,
|
||||
downvotes = excluded.downvotes;
|
||||
|
||||
-- Re-enable the triggers
|
||||
ALTER TABLE person_actions ENABLE TRIGGER ALL;
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
ALTER TABLE community
|
||||
ALTER CONSTRAINT community_instance_id_fkey DEFERRABLE INITIALLY DEFERRED;
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
-- We should remove existing deferrable constraints, as they're potentially dangerous.
|
||||
--
|
||||
-- This is the only one I could find after doing a DB dump.
|
||||
ALTER TABLE community
|
||||
ALTER CONSTRAINT community_instance_id_fkey NOT DEFERRABLE;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
CREATE TABLE person_post_mention (
|
||||
id serial PRIMARY KEY,
|
||||
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
recipient_id int REFERENCES person (id) ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
post_id int REFERENCES post (id) ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
read bool NOT NULL DEFAULT FALSE,
|
||||
|
@ -27,7 +27,7 @@ CREATE TABLE comment_reply (
|
|||
);
|
||||
|
||||
CREATE TABLE inbox_combined (
|
||||
id serial PRIMARY KEY,
|
||||
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
comment_reply_id int REFERENCES comment_reply (id) ON UPDATE CASCADE ON DELETE CASCADE UNIQUE,
|
||||
person_comment_mention_id int REFERENCES person_comment_mention (id) ON UPDATE CASCADE ON DELETE CASCADE UNIQUE,
|
||||
person_post_mention_id int REFERENCES person_post_mention (id) ON UPDATE CASCADE ON DELETE CASCADE UNIQUE,
|
||||
|
@ -109,7 +109,7 @@ FROM
|
|||
comment_reply;
|
||||
|
||||
ALTER TABLE ONLY person_post_mention
|
||||
ADD CONSTRAINT person_post_mention_unique UNIQUE (recipient_id, post_id);
|
||||
ADD CONSTRAINT person_post_mention_recipient_id_post_id_key UNIQUE (recipient_id, post_id);
|
||||
|
||||
ALTER TABLE inbox_combined
|
||||
ADD CONSTRAINT inbox_combined_check CHECK (num_nonnulls (comment_reply_id, person_comment_mention_id, person_post_mention_id, private_message_id) = 1);
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
DROP INDEX idx_registration_application_admin, idx_admin_allow_instance_admin, idx_admin_block_instance_admin, idx_admin_purge_comment_admin, idx_admin_purge_community_admin, idx_admin_purge_person_admin, idx_admin_purge_post_admin, idx_mod_remove_comment_comment, idx_person_liked_combined_comment, idx_person_saved_combined_comment, idx_comment_report_creator, idx_community_report_creator, idx_post_report_creator, idx_private_message_creator, idx_private_message_report_creator, idx_admin_purge_post_community, idx_mod_add_community_community, idx_mod_ban_from_community_community, idx_mod_change_community_visibility_community, idx_mod_remove_community_community, idx_mod_transfer_community_community, idx_tag_community, idx_community_actions_follow_approver, idx_admin_allow_instance_instance, idx_admin_block_instance_instance, idx_community_instance, idx_instance_actions_instance, idx_mod_ban_instance, idx_multi_community_instance, idx_person_instance, idx_community_language_language, idx_local_user_language_language, idx_site_language_language, idx_email_verification_user, idx_oauth_account_user, idx_password_reset_request_user, idx_modlog_combined_mod_change_community_visibility_id, idx_mod_add_community_mod, idx_mod_add_mod, idx_mod_ban_from_community_mod, idx_mod_ban_mod, idx_mod_change_community_visibility_mod, idx_mod_feature_post_mod, idx_mod_lock_post_mod, idx_mod_remove_comment_mod, idx_mod_remove_community_mod, idx_mod_remove_post_mod, idx_mod_transfer_community_mod, idx_local_site_multi_comm_follower, idx_search_combined_multi_community, idx_mod_add_community_other_person, idx_mod_add_other_person, idx_mod_ban_from_community_other_person, idx_mod_other_person, idx_mod_transfer_community_other_person, idx_admin_purge_comment_post, idx_mod_feature_post_post, idx_mod_lock_post_post, idx_mod_remove_post_post, idx_person_liked_combined_post, idx_person_saved_combined_post, idx_private_message_recipient, idx_comment_report_resolver, idx_community_report_resolver, idx_post_report_resolver, idx_private_message_report_resolver, idx_local_site_suggested_communities, idx_post_tag_tag, idx_local_image_thumbnail_post;
|
||||
DROP INDEX idx_registration_application_admin, idx_admin_allow_instance_admin, idx_admin_block_instance_admin, idx_admin_purge_comment_admin, idx_admin_purge_community_admin, idx_admin_purge_person_admin, idx_admin_purge_post_admin, idx_mod_remove_comment_comment, idx_person_liked_combined_comment, idx_person_saved_combined_comment, idx_comment_report_creator, idx_community_report_creator, idx_post_report_creator, idx_private_message_creator, idx_private_message_report_creator, idx_admin_purge_post_community, idx_mod_add_community_community, idx_mod_ban_from_community_community, idx_mod_change_community_visibility_community, idx_mod_remove_community_community, idx_mod_transfer_community_community, idx_tag_community, idx_community_actions_follow_approver, idx_admin_allow_instance_instance, idx_admin_block_instance_instance, idx_community_instance, idx_mod_ban_instance, idx_multi_community_instance, idx_person_instance, idx_community_language_language, idx_local_user_language_language, idx_site_language_language, idx_email_verification_user, idx_oauth_account_user, idx_password_reset_request_user, idx_modlog_combined_mod_change_community_visibility_id, idx_mod_add_community_mod, idx_mod_add_mod, idx_mod_ban_from_community_mod, idx_mod_ban_mod, idx_mod_change_community_visibility_mod, idx_mod_feature_post_mod, idx_mod_lock_post_mod, idx_mod_remove_comment_mod, idx_mod_remove_community_mod, idx_mod_remove_post_mod, idx_mod_transfer_community_mod, idx_local_site_multi_comm_follower, idx_search_combined_multi_community, idx_mod_add_community_other_person, idx_mod_add_other_person, idx_mod_ban_from_community_other_person, idx_mod_other_person, idx_mod_transfer_community_other_person, idx_admin_purge_comment_post, idx_mod_feature_post_post, idx_mod_lock_post_post, idx_mod_remove_post_post, idx_person_liked_combined_post, idx_person_saved_combined_post, idx_private_message_recipient, idx_comment_report_resolver, idx_community_report_resolver, idx_post_report_resolver, idx_private_message_report_resolver, idx_local_site_suggested_communities, idx_post_tag_tag, idx_local_image_thumbnail_post;
|
||||
|
||||
|
|
|
@ -50,8 +50,6 @@ CREATE INDEX idx_admin_block_instance_instance ON admin_block_instance (instance
|
|||
|
||||
CREATE INDEX idx_community_instance ON community (instance_id);
|
||||
|
||||
CREATE INDEX idx_instance_actions_instance ON instance_actions (instance_id);
|
||||
|
||||
CREATE INDEX idx_mod_ban_instance ON mod_ban (instance_id);
|
||||
|
||||
CREATE INDEX idx_multi_community_instance ON multi_community (instance_id);
|
||||
|
|
56
scripts/query_testing/bulk_upsert_timings.md
Normal file
56
scripts/query_testing/bulk_upsert_timings.md
Normal file
|
@ -0,0 +1,56 @@
|
|||
# post_read -> post_actions bulk upsert timings
|
||||
|
||||
## normal, 1 month: 491s
|
||||
|
||||
Insert on post_actions (cost=0.57..371215.69 rows=0 width=0) (actual time=169235.026..169235.026 rows=0 loops=1) Conflict Resolution: UPDATE Conflict Arbiter Indexes: post_actions_pkey Tuples Inserted: 5175253 Conflicting Tuples: 0 -> Index Scan using idx_post_read_published_desc on post_read (cost=0.57..371215.69 rows=5190811 width=58) (actual time=47.762..39310.551 rows=5175253 loops=1) Index Cond: (published > (CURRENT_DATE - '6 mons'::interval)) Planning Time: 0.234 ms Trigger for constraint post_actions_person_id_fkey: time=118828.666 calls=5175253 Trigger for constraint post_actions_post_id_fkey: time=203098.355 calls=5175253 JIT: Functions: 6 Options: Inlining false, Optimization false, Expressions true, Deforming true Timing: Generation 0.448 ms, Inlining 0.000 ms, Optimization 0.201 ms, Emission 44.721 ms, Total 45.369 ms Execution Time: 491991.365 ms (15 rows)
|
||||
|
||||
## disabled triggers, keep pkey, on conflict: 167s
|
||||
|
||||
Insert on post_actions (cost=0.57..371215.69 rows=0 width=0) (actual time=167261.176..167261.176 rows=0 loops=1) Conflict Resolution: UPDATE Conflict Arbiter Indexes: post_actions_pkey Tuples Inserted: 5175253 Conflicting Tuples: 0 -> Index Scan using idx_tmp_1 on post_read (cost=0.57..371215.69 rows=5190811 width=58) (actual time=5.604..59193.030 rows=5175253 loops=1) Index Cond: (published > (CURRENT_DATE - '6 mons'::interval)) Planning Time: 0.147 ms JIT: Functions: 6 Options: Inlining false, Optimization false, Expressions true, Deforming true Timing: Generation 0.490 ms, Inlining 0.000 ms, Optimization 0.197 ms, Emission 3.989 ms, Total 4.675 ms Execution Time: 167261.807 ms
|
||||
|
||||
## disabled triggers, with pkey, insert only: 91s
|
||||
|
||||
Insert on post_actions (cost=0.57..371215.69 rows=0 width=0) (actual time=91820.768..91820.769 rows=0 loops=1) -> Index Scan using idx_tmp_1 on post_read (cost=0.57..371215.69 rows=5190811 width=58) (actual time=5.482..40066.185 rows=5175253 loops=1) Index Cond: (published > (CURRENT_DATE - '6 mons'::interval)) Planning Time: 0.098 ms JIT: Functions: 5 Options: Inlining false, Optimization false, Expressions true, Deforming true Timing: Generation 0.490 ms, Inlining 0.000 ms, Optimization 0.208 ms, Emission 3.894 ms, Total 4.592 ms Execution Time: 91821.724 ms
|
||||
|
||||
## disabled triggers, no pkey, insert only: 57s
|
||||
|
||||
Insert on post_actions (cost=0.57..371215.69 rows=0 width=0) (actual time=56797.431..56797.432 rows=0 loops=1) -> Index Scan using idx_tmp_1 on post_read (cost=0.57..371215.69 rows=5190811 width=58) (actual time=4.827..27903.829 rows=5175253 loops=1) Index Cond: (published > (CURRENT_DATE - '6 mons'::interval)) Planning Time: 0.096 ms JIT: Functions: 5 Options: Inlining false, Optimization false, Expressions true, Deforming true Timing: Generation 0.390 ms, Inlining 0.000 ms, Optimization 0.232 ms, Emission 3.373 ms, Total 3.994 ms Execution Time: 56798.022 ms
|
||||
|
||||
## disabled triggers, merge instead of upsert: 77s
|
||||
|
||||
Merge on post_actions pa (cost=34.06..280379.97 rows=0 width=0) (actual time=76988.823..76988.825 rows=0 loops=1) Tuples: inserted=5175253 -> Hash Left Join (cost=34.06..280379.97 rows=1098137 width=28) (actual time=8.109..12202.884 rows=5175253 loops=1) Hash Cond: ((post_read.person_id = pa.person_id) AND (post_read.post_id = pa.post_id)) -> Index Scan using idx_tmp_1 on post_read (cost=0.56..274581.25 rows=1098137 width=22) (actual time=8.094..11432.132 rows=5175253 loops=1) Index Cond: (published > (CURRENT_DATE - '6 mons'::interval)) -> Hash (cost=19.40..19.40 rows=940 width=14) (actual time=0.003..0.004 rows=0 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 8kB -> Seq Scan on post_actions pa (cost=0.00..19.40 rows=940 width=14) (actual time=0.003..0.003 rows=0 loops=1) Planning Time: 0.468 ms JIT: Functions: 17 Options: Inlining false, Optimization false, Expressions true, Deforming true Timing: Generation 0.897 ms, Inlining 0.000 ms, Optimization 0.399 ms, Emission 7.650 ms, Total 8.946 ms Execution Time: 76989.946 ms
|
||||
|
||||
## disabled triggers, merge, no pkey: 39s
|
||||
|
||||
Merge on post_actions pa (cost=297488.30..303957.64 rows=0 width=0) (actual time=39009.474..39009.477 rows=0 loops=1) Tuples: inserted=5175253 -> Hash Right Join (cost=297488.30..303957.64 rows=1098137 width=28) (actual time=3412.832..5353.677 rows=5175253 loops=1) Hash Cond: ((pa.person_id = post_read.person_id) AND (pa.post_id = post_read.post_id)) -> Seq Scan on post_actions pa (cost=0.00..19.40 rows=940 width=14) (actual time=0.004..0.005 rows=0 loops=1) -> Hash (cost=274581.25..274581.25 rows=1098137 width=22) (actual time=3412.178..3412.180 rows=5175253 loops=1) Buckets: 131072 (originally 131072) Batches: 64 (originally 16) Memory Usage: 7169kB -> Index Scan using idx_tmp_1 on post_read (cost=0.56..274581.25 rows=1098137 width=22) (actual time=8.495..2299.278 rows=5175253 loops=1) Index Cond: (published > (CURRENT_DATE - '6 mons'::interval)) Planning Time: 0.465 ms JIT: Functions: 17 Options: Inlining false, Optimization false, Expressions true, Deforming true Timing: Generation 0.988 ms, Inlining 0.000 ms, Optimization 0.350 ms, Emission 8.127 ms, Total 9.465 ms Execution Time: 39011.515 ms
|
||||
|
||||
## same as above, full table: 425s
|
||||
|
||||
Merge on post_actions pa (cost=1478580.50..1520165.83 rows=0 width=0) (actual time=425751.243..425751.245 rows=0 loops=1) Tuples: inserted=33519660 -> Hash Right Join (cost=1478580.50..1520165.83 rows=7091220 width=28) (actual time=72968.237..120866.662 rows=33519660 loops=1) Hash Cond: ((pa.person_id = pr.person_id) AND (pa.post_id = pr.post_id)) -> Seq Scan on post_actions pa (cost=0.00..19.40 rows=940 width=14) (actual time=0.004..0.004 rows=0 loops=1) -> Hash (cost=1330661.20..1330661.20 rows=7091220 width=22) (actual time=72967.590..72967.591 rows=33519660 loops=1) Buckets: 131072 (originally 131072) Batches: 256 (originally 64) Memory Usage: 7927kB -> Seq Scan on post_read pr (cost=0.00..1330661.20 rows=7091220 width=22) (actual time=103.545..51892.728 rows=33519660 loops=1) Planning Time: 0.393 ms JIT: Functions: 14 Options: Inlining true, Optimization true, Expressions true, Deforming true Timing: Generation 0.840 ms, Inlining 11.303 ms, Optimization 45.211 ms, Emission 40.003 ms, Total 97.357 ms Execution Time: 425753.438 ms
|
||||
|
||||
## disabled triggers, merge, with pkey, full table: 587s
|
||||
|
||||
Merge on post_actions pa (cost=19.47..1367909.58 rows=0 width=0) (actual time=587295.757..587295.759 rows=0 loops=1) Tuples: inserted=33519660 -> Hash Left Join (cost=19.47..1367909.58 rows=7091220 width=28) (actual time=77.291..46496.679 rows=33519660 loops=1) Hash Cond: ((pr.person_id = pa.person_id) AND (pr.post_id = pa.post_id)) -> Seq Scan on post_read pr (cost=0.00..1330661.20 rows=7091220 width=22) (actual time=77.266..41178.528 rows=33519660 loops=1) -> Hash (cost=19.40..19.40 rows=5 width=14) (actual time=0.006..0.007 rows=0 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 8kB -> Seq Scan on post_actions pa (cost=0.00..19.40 rows=5 width=14) (actual time=0.006..0.006 rows=0 loops=1) Filter: (read IS NULL) Planning Time: 0.428 ms JIT: Functions: 16 Options: Inlining true, Optimization true, Expressions true, Deforming true Timing: Generation 0.922 ms, Inlining 6.324 ms, Optimization 37.862 ms, Emission 33.076 ms, Total 78.183 ms Execution Time: 587297.207 ms (15 rows)
|
||||
|
||||
## disabled triggers, merge, no pkey, full table: 359s
|
||||
|
||||
## disabled triggers, merge, no pkey, person_post_aggs after post_read: 1260s
|
||||
|
||||
## disabled triggers, no pkey, post_read + person_post_aggs union all with group by insert (no upsert or merge): 402s
|
||||
|
||||
### Merge example:
|
||||
|
||||
```sql
|
||||
EXPLAIN ANALYZE MERGE INTO post_actions pa
|
||||
USING post_read pr ON (pa.person_id = pr.person_id
|
||||
AND pa.post_id = pr.post_id
|
||||
)
|
||||
WHEN MATCHED THEN
|
||||
UPDATE SET
|
||||
read = pr.published
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (person_id, post_id, read)
|
||||
VALUES (pr.person_id, pr.post_id, pr.published);
|
||||
```
|
||||
|
||||
## comment aggregate bulk update: 3881s / 65m
|
|
@ -155,7 +155,7 @@ pub async fn start_lemmy_server(args: CmdArgs) -> LemmyResult<()> {
|
|||
options = options.limit(number);
|
||||
}
|
||||
|
||||
lemmy_db_schema_setup::run(options, &SETTINGS.get_database_url())?;
|
||||
lemmy_db_schema_setup::run(options, &SETTINGS.get_database_url_with_options()?)?;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
if all && subcommand == MigrationSubcommand::Run {
|
||||
|
|
Loading…
Reference in a new issue