From f1377ce7fbf599a979a8934d8d226aa5ee380325 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 9 Feb 2021 16:35:01 +0000 Subject: [PATCH] Issue 9906: Improved view speed --- database.sql | 51 +++++++++++++++++++++------------- src/Model/Item.php | 1 + src/Model/Post.php | 7 +---- static/dbstructure.config.php | 14 ++++++++-- static/dbview.config.php | 34 +++++++++++------------ tests/datasets/api.fixture.php | 6 ++-- update.php | 13 ++++++++- 7 files changed, 76 insertions(+), 50 deletions(-) diff --git a/database.sql b/database.sql index 4ad484e192..3f1e54ab46 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2021.03-dev (Red Hot Poker) --- DB_UPDATE_VERSION 1398 +-- DB_UPDATE_VERSION 1399 -- ------------------------------------------ @@ -1164,12 +1164,24 @@ CREATE TABLE IF NOT EXISTS `post-thread-user` ( `mention` boolean NOT NULL DEFAULT '0' COMMENT '', `pubmail` boolean NOT NULL DEFAULT '0' COMMENT '', `forum_mode` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '', + `contact-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'contact.id', + `unseen` boolean NOT NULL DEFAULT '1' COMMENT 'post has not been seen', + `hidden` boolean NOT NULL DEFAULT '0' COMMENT 'Marker to hide the post from the user', + `origin` boolean NOT NULL DEFAULT '0' COMMENT 'item originated at this site', + `psid` int unsigned COMMENT 'ID of the permission set of this post', + `post-user-id` int unsigned COMMENT 'Id of the post-user table', PRIMARY KEY(`uid`,`uri-id`), INDEX `uid_wall` (`uid`,`wall`), INDEX `uid_pinned` (`uid`,`pinned`), INDEX `uri-id` (`uri-id`), + INDEX `contact-id` (`contact-id`), + INDEX `psid` (`psid`), + INDEX `post-user-id` (`post-user-id`), FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE, - FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE + FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE, + FOREIGN KEY (`contact-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE, + FOREIGN KEY (`psid`) REFERENCES `permissionset` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT, + FOREIGN KEY (`post-user-id`) REFERENCES `post-user` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Thread related data per user'; -- @@ -1191,6 +1203,7 @@ CREATE TABLE IF NOT EXISTS `post-user` ( INDEX `uri-id` (`uri-id`), INDEX `contact-id` (`contact-id`), INDEX `psid` (`psid`), + INDEX `uid_hidden` (`uid`,`hidden`), FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE, FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE, FOREIGN KEY (`contact-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE, @@ -1645,15 +1658,15 @@ CREATE VIEW `post-thread-view` AS SELECT `item`.`visible` AS `visible`, `post-thread-user`.`starred` AS `starred`, `item`.`bookmark` AS `bookmark`, - `post-user`.`unseen` AS `unseen`, + `post-thread-user`.`unseen` AS `unseen`, `item`.`deleted` AS `deleted`, - `post-user`.`origin` AS `origin`, + `post-thread-user`.`origin` AS `origin`, `post-thread-user`.`forum_mode` AS `forum_mode`, `item`.`mention` AS `mention`, `item`.`global` AS `global`, `post-thread`.`network` AS `network`, `item`.`vid` AS `vid`, - `post-user`.`psid` AS `psid`, + `post-thread-user`.`psid` AS `psid`, IF (`item`.`vid` IS NULL, '', `verb`.`name`) AS `verb`, `post-content`.`title` AS `title`, `post-content`.`content-warning` AS `content-warning`, @@ -1671,7 +1684,7 @@ CREATE VIEW `post-thread-view` AS SELECT `post-content`.`target-type` AS `target-type`, `post-content`.`target` AS `target`, `post-content`.`resource-id` AS `resource-id`, - `post-user`.`contact-id` AS `contact-id`, + `post-thread-user`.`contact-id` AS `contact-id`, `contact`.`url` AS `contact-link`, `contact`.`addr` AS `contact-addr`, `contact`.`name` AS `contact-name`, @@ -1729,10 +1742,10 @@ CREATE VIEW `post-thread-view` AS SELECT `post-delivery-data`.`queue_count` AS `delivery_queue_count`, `post-delivery-data`.`queue_done` AS `delivery_queue_done`, `post-delivery-data`.`queue_failed` AS `delivery_queue_failed`, - IF (`post-user`.`psid` IS NULL, '', `permissionset`.`allow_cid`) AS `allow_cid`, - IF (`post-user`.`psid` IS NULL, '', `permissionset`.`allow_gid`) AS `allow_gid`, - IF (`post-user`.`psid` IS NULL, '', `permissionset`.`deny_cid`) AS `deny_cid`, - IF (`post-user`.`psid` IS NULL, '', `permissionset`.`deny_gid`) AS `deny_gid`, + IF (`post-thread-user`.`psid` IS NULL, '', `permissionset`.`allow_cid`) AS `allow_cid`, + IF (`post-thread-user`.`psid` IS NULL, '', `permissionset`.`allow_gid`) AS `allow_gid`, + IF (`post-thread-user`.`psid` IS NULL, '', `permissionset`.`deny_cid`) AS `deny_cid`, + IF (`post-thread-user`.`psid` IS NULL, '', `permissionset`.`deny_gid`) AS `deny_gid`, `item`.`event-id` AS `event-id`, `event`.`created` AS `event-created`, `event`.`edited` AS `event-edited`, @@ -1754,9 +1767,8 @@ CREATE VIEW `post-thread-view` AS SELECT `parent-item-author`.`network` AS `parent-author-network` FROM `post-thread` STRAIGHT_JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-thread`.`uri-id` - STRAIGHT_JOIN `post-user` ON `post-user`.`uri-id` = `post-thread`.`uri-id` STRAIGHT_JOIN `item` ON `item`.`uri-id` = `post-thread`.`uri-id` AND `item`.`uid` = `post-thread-user`.`uid` - STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-user`.`contact-id` + STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id` STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `post-thread`.`author-id` STRAIGHT_JOIN `contact` AS `owner` ON `owner`.`id` = `post-thread`.`owner-id` STRAIGHT_JOIN `contact` AS `causer` ON `causer`.`id` = `post-thread`.`causer-id` @@ -1764,8 +1776,8 @@ CREATE VIEW `post-thread-view` AS SELECT LEFT JOIN `event` ON `event`.`id` = `item`.`event-id` LEFT JOIN `diaspora-interaction` ON `diaspora-interaction`.`uri-id` = `post-thread`.`uri-id` LEFT JOIN `post-content` ON `post-content`.`uri-id` = `post-thread`.`uri-id` - LEFT JOIN `post-delivery-data` ON `post-delivery-data`.`uri-id` = `post-thread`.`uri-id` AND `post-user`.`origin` - LEFT JOIN `permissionset` ON `permissionset`.`id` = `post-user`.`psid` + LEFT JOIN `post-delivery-data` ON `post-delivery-data`.`uri-id` = `post-thread`.`uri-id` AND `post-thread-user`.`origin` + LEFT JOIN `permissionset` ON `permissionset`.`id` = `post-thread-user`.`psid` STRAIGHT_JOIN `item` AS `parent-item` ON `parent-item`.`id` = `item`.`parent` STRAIGHT_JOIN `contact` AS `parent-item-author` ON `parent-item-author`.`id` = `parent-item`.`author-id`; @@ -1852,19 +1864,18 @@ CREATE VIEW `network-thread-view` AS SELECT `post-thread-user`.`starred` AS `starred`, `post-thread-user`.`mention` AS `mention`, `post-thread`.`network` AS `network`, - `post-user`.`contact-id` AS `contact-id`, + `post-thread-user`.`contact-id` AS `contact-id`, `ownercontact`.`contact-type` AS `contact-type` FROM `post-thread` STRAIGHT_JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-thread`.`uri-id` - STRAIGHT_JOIN `post-user` ON `post-user`.`uri-id` = `post-thread`.`uri-id` AND `post-user`.`uid` = `post-thread-user`.`uid` STRAIGHT_JOIN `item` ON `item`.`uri-id` = `post-thread`.`uri-id` AND `item`.`uid` = `post-thread-user`.`uid` - STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-user`.`contact-id` - LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `post-user`.`uid` AND `author`.`cid` = `post-thread`.`author-id` - LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `post-user`.`uid` AND `owner`.`cid` = `post-thread`.`owner-id` + STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id` + LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `post-thread-user`.`uid` AND `author`.`cid` = `post-thread`.`author-id` + LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `post-thread-user`.`uid` AND `owner`.`cid` = `post-thread`.`owner-id` LEFT JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread`.`owner-id` WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated` AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`) - AND (`post-user`.`hidden` IS NULL OR NOT `post-user`.`hidden`) + AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`) AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`) AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`); diff --git a/src/Model/Item.php b/src/Model/Item.php index cd484e6789..0fe26e1da9 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -1015,6 +1015,7 @@ class Item } if ($item['gravity'] == GRAVITY_PARENT) { + $item['post-user-id'] = $id; Post\ThreadUser::insert($item['uri-id'], $item['uid'], $item); } diff --git a/src/Model/Post.php b/src/Model/Post.php index 29cbb26952..a3d537b3da 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -464,12 +464,7 @@ class Post if (!empty($update_fields)) { $rows = DBA::selectToArray('post-view', ['post-user-id'], $thread_condition); $thread_puids = array_column($rows, 'post-user-id'); - - $post_thread_condition = DBA::collapseCondition(['id' => $thread_puids]); - - $post_thread_condition[0] = "EXISTS(SELECT `id` FROM `post-user` WHERE " . - $post_thread_condition[0] . " AND `uri-id` = `post-thread-user`.`uri-id` AND `uid` = `post-thread-user`.`uid`)"; - if (!DBA::update('post-thread-user', $update_fields, $post_thread_condition)) { + if (!DBA::update('post-thread-user', $update_fields, ['post-user-id' => $thread_puids])) { DBA::rollback(); Logger::notice('Updating post-thread-user failed', ['fields' => $update_fields, 'condition' => $condition]); return false; diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 1a120969d1..1817145714 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1398); + define('DB_UPDATE_VERSION', 1399); } return [ @@ -1215,13 +1215,22 @@ return [ "wall" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "This item was posted to the wall of uid"], "mention" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""], "pubmail" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""], - "forum_mode" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""] + "forum_mode" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""], + "contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "contact.id"], + "unseen" => ["type" => "boolean", "not null" => "1", "default" => "1", "comment" => "post has not been seen"], + "hidden" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Marker to hide the post from the user"], + "origin" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item originated at this site"], + "psid" => ["type" => "int unsigned", "foreign" => ["permissionset" => "id", "on delete" => "restrict"], "comment" => "ID of the permission set of this post"], + "post-user-id" => ["type" => "int unsigned", "foreign" => ["post-user" => "id"], "comment" => "Id of the post-user table"], ], "indexes" => [ "PRIMARY" => ["uid", "uri-id"], "uid_wall" => ["uid", "wall"], "uid_pinned" => ["uid", "pinned"], "uri-id" => ["uri-id"], + "contact-id" => ["contact-id"], + "psid" => ["psid"], + "post-user-id" => ["post-user-id"], ] ], "post-user" => [ @@ -1244,6 +1253,7 @@ return [ "uri-id" => ["uri-id"], "contact-id" => ["contact-id"], "psid" => ["psid"], + "uid_hidden" => ["uid", "hidden"], ], ], "post-user-notification" => [ diff --git a/static/dbview.config.php b/static/dbview.config.php index 98fe5fba76..6b48a9532e 100644 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -221,15 +221,15 @@ "visible" => ["item", "visible"], "starred" => ["post-thread-user", "starred"], "bookmark" => ["item", "bookmark"], - "unseen" => ["post-user", "unseen"], + "unseen" => ["post-thread-user", "unseen"], "deleted" => ["item", "deleted"], - "origin" => ["post-user", "origin"], + "origin" => ["post-thread-user", "origin"], "forum_mode" => ["post-thread-user", "forum_mode"], "mention" => ["item", "mention"], "global" => ["item", "global"], "network" => ["post-thread", "network"], "vid" => ["item", "vid"], - "psid" => ["post-user", "psid"], + "psid" => ["post-thread-user", "psid"], "verb" => "IF (`item`.`vid` IS NULL, '', `verb`.`name`)", "title" => ["post-content", "title"], "content-warning" => ["post-content", "content-warning"], @@ -247,7 +247,7 @@ "target-type" => ["post-content", "target-type"], "target" => ["post-content", "target"], "resource-id" => ["post-content", "resource-id"], - "contact-id" => ["post-user", "contact-id"], + "contact-id" => ["post-thread-user", "contact-id"], "contact-link" => ["contact", "url"], "contact-addr" => ["contact", "addr"], "contact-name" => ["contact", "name"], @@ -305,10 +305,10 @@ "delivery_queue_count" => ["post-delivery-data", "queue_count"], "delivery_queue_done" => ["post-delivery-data", "queue_done"], "delivery_queue_failed" => ["post-delivery-data", "queue_failed"], - "allow_cid" => "IF (`post-user`.`psid` IS NULL, '', `permissionset`.`allow_cid`)", - "allow_gid" => "IF (`post-user`.`psid` IS NULL, '', `permissionset`.`allow_gid`)", - "deny_cid" => "IF (`post-user`.`psid` IS NULL, '', `permissionset`.`deny_cid`)", - "deny_gid" => "IF (`post-user`.`psid` IS NULL, '', `permissionset`.`deny_gid`)", + "allow_cid" => "IF (`post-thread-user`.`psid` IS NULL, '', `permissionset`.`allow_cid`)", + "allow_gid" => "IF (`post-thread-user`.`psid` IS NULL, '', `permissionset`.`allow_gid`)", + "deny_cid" => "IF (`post-thread-user`.`psid` IS NULL, '', `permissionset`.`deny_cid`)", + "deny_gid" => "IF (`post-thread-user`.`psid` IS NULL, '', `permissionset`.`deny_gid`)", "event-id" => ["item", "event-id"], "event-created" => ["event", "created"], "event-edited" => ["event", "edited"], @@ -331,9 +331,8 @@ ], "query" => "FROM `post-thread` STRAIGHT_JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-thread`.`uri-id` - STRAIGHT_JOIN `post-user` ON `post-user`.`uri-id` = `post-thread`.`uri-id` STRAIGHT_JOIN `item` ON `item`.`uri-id` = `post-thread`.`uri-id` AND `item`.`uid` = `post-thread-user`.`uid` - STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-user`.`contact-id` + STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id` STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `post-thread`.`author-id` STRAIGHT_JOIN `contact` AS `owner` ON `owner`.`id` = `post-thread`.`owner-id` STRAIGHT_JOIN `contact` AS `causer` ON `causer`.`id` = `post-thread`.`causer-id` @@ -341,8 +340,8 @@ LEFT JOIN `event` ON `event`.`id` = `item`.`event-id` LEFT JOIN `diaspora-interaction` ON `diaspora-interaction`.`uri-id` = `post-thread`.`uri-id` LEFT JOIN `post-content` ON `post-content`.`uri-id` = `post-thread`.`uri-id` - LEFT JOIN `post-delivery-data` ON `post-delivery-data`.`uri-id` = `post-thread`.`uri-id` AND `post-user`.`origin` - LEFT JOIN `permissionset` ON `permissionset`.`id` = `post-user`.`psid` + LEFT JOIN `post-delivery-data` ON `post-delivery-data`.`uri-id` = `post-thread`.`uri-id` AND `post-thread-user`.`origin` + LEFT JOIN `permissionset` ON `permissionset`.`id` = `post-thread-user`.`psid` STRAIGHT_JOIN `item` AS `parent-item` ON `parent-item`.`id` = `item`.`parent` STRAIGHT_JOIN `contact` AS `parent-item-author` ON `parent-item-author`.`id` = `parent-item`.`author-id`" ], @@ -420,20 +419,19 @@ "starred" => ["post-thread-user", "starred"], "mention" => ["post-thread-user", "mention"], "network" => ["post-thread", "network"], - "contact-id" => ["post-user", "contact-id"], + "contact-id" => ["post-thread-user", "contact-id"], "contact-type" => ["ownercontact", "contact-type"], ], "query" => "FROM `post-thread` STRAIGHT_JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-thread`.`uri-id` - STRAIGHT_JOIN `post-user` ON `post-user`.`uri-id` = `post-thread`.`uri-id` AND `post-user`.`uid` = `post-thread-user`.`uid` STRAIGHT_JOIN `item` ON `item`.`uri-id` = `post-thread`.`uri-id` AND `item`.`uid` = `post-thread-user`.`uid` - STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-user`.`contact-id` - LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `post-user`.`uid` AND `author`.`cid` = `post-thread`.`author-id` - LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `post-user`.`uid` AND `owner`.`cid` = `post-thread`.`owner-id` + STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id` + LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `post-thread-user`.`uid` AND `author`.`cid` = `post-thread`.`author-id` + LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `post-thread-user`.`uid` AND `owner`.`cid` = `post-thread`.`owner-id` LEFT JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread`.`owner-id` WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated` AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`) - AND (`post-user`.`hidden` IS NULL OR NOT `post-user`.`hidden`) + AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`) AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`) AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`)" ], diff --git a/tests/datasets/api.fixture.php b/tests/datasets/api.fixture.php index 8a683da958..7a7e2194fd 100644 --- a/tests/datasets/api.fixture.php +++ b/tests/datasets/api.fixture.php @@ -220,21 +220,21 @@ return [ 'author-id' => 42, 'owner-id' => 42, 'causer-id' => 42, - 'network' => Protocol::DFRN, + 'network' => Protocol::DFRN, ], [ 'uri-id' => 3, 'author-id' => 43, 'owner-id' => 43, 'causer-id' => 43, - 'network' => Protocol::DFRN, + 'network' => Protocol::DFRN, ], [ 'uri-id' => 6, 'author-id' => 44, 'owner-id' => 44, 'causer-id' => 44, - 'network' => Protocol::DFRN, + 'network' => Protocol::DFRN, ], ], 'post-thread-user' => [ diff --git a/update.php b/update.php index f9c0f16df0..9b5c7ac6fb 100644 --- a/update.php +++ b/update.php @@ -757,5 +757,16 @@ function update_1398() } return Update::SUCCESS; - +} + +function update_1399() +{ + if (!DBA::e("UPDATE `post-thread-user` INNER JOIN `post-user` ON `post-user`.`uid` = `post-thread-user`.`uid` AND `post-user`.`uri-id` = `post-thread-user`.`uri-id` + SET `post-thread-user`.`contact-id` = `post-user`.`contact-id`, `post-thread-user`.`unseen` = `post-user`.`unseen`, + `post-thread-user`.`hidden` = `post-user`.`hidden`, `post-thread-user`.`origin` = `post-user`.`origin`, + `post-thread-user`.`psid` = `post-user`.`psid`, `post-thread-user`.`post-user-id` = `post-user`.`id`")) { + return Update::FAILED; + } + + return Update::SUCCESS; }