Mysql优化算法,用于保存历史变化的变种

问题描述 投票:0回答:1

我有一个主表与实际的用户信息

CREATE TABLE user
(
  id                            bigint                              NOT NULL
    PRIMARY KEY,
  updated                       timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  username                      varchar(40)                         NULL,
  full_name                     varchar(255)                        NULL,
  biography                     varchar(512)                        NULL,
  profile_pic_id                varchar(40)                         NULL,
  profile_pic_url               varchar(255)                        NULL,
  hd_profile_pic_url            varchar(255)                        NULL,
  follower_count                int                                 NULL,
  following_count               int                                 NULL,
  media_count                   int                                 NULL,
  usertags_count                int                                 NULL,
  following_tag_count           int                                 NULL,
  external_url                  longtext                            NULL,
  reel_auto_archive             varchar(255)                        NULL,
  has_biography_translation     tinyint(1)                          NULL,
  has_anonymous_profile_picture tinyint(1)                          NULL,
  has_highlight_reels           tinyint(1)                          NULL,
  is_business                   tinyint(1)                          NULL,
  is_active                     tinyint(1)                          NULL,
  is_verified                   tinyint(1)                          NULL,
  is_private                    tinyint(1)                          NULL,
  is_blocked                    tinyint(1)                          NULL
)

保存历史记录的表几乎相同:

CREATE TABLE user_history
(
  id                            int AUTO_INCREMENT
    PRIMARY KEY,
  user_id                  bigint                              NULL,
  added                         timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
  username                      varchar(40)                         NULL,
  full_name                     varchar(255)                        NULL,
  biography                     varchar(512)                        NULL,
  profile_pic_id                varchar(40)                         NULL,
  profile_pic_url               varchar(255)                        NULL,
  hd_profile_pic_url            varchar(255)                        NULL,
  follower_count                int                                 NULL,
  following_count               int                                 NULL,
  media_count                   int                                 NULL,
  usertags_count                int                                 NULL,
  following_tag_count           int                                 NULL,
  external_url                  longtext                            NULL,
  reel_auto_archive             varchar(255)                        NULL,
  has_biography_translation     tinyint(1)                          NULL,
  has_anonymous_profile_picture tinyint(1)                          NULL,
  has_highlight_reels           tinyint(1)                          NULL,
  is_business                   tinyint(1)                          NULL,
  is_active                     tinyint(1)                          NULL,
  is_verified                   tinyint(1)                          NULL,
  is_private                    tinyint(1)                          NULL,
  is_blocked                    tinyint(1)                          NULL,
  CONSTRAINT FK_F19A7E3C5AFE2D44
    FOREIGN KEY (user_id) REFERENCES user (id)
)
  COLLATE = utf8mb4_unicode_ci;

CREATE INDEX IDX_F19A7E3C5AFE2D44
  ON user_history (user_id);

拯救历史的老虎:

CREATE TRIGGER user_update
  AFTER UPDATE
  ON user
  FOR EACH ROW
BEGIN
  INSERT INTO `user_history` (`user_id`, `username`, `full_name`, `biography`, `profile_pic_id`,
                                   `profile_pic_url`, `hd_profile_pic_url`, `follower_count`, `following_count`,
                                   `media_count`, `usertags_count`, `following_tag_count`, `external_url`,
                                   `reel_auto_archive`, `has_biography_translation`, `has_anonymous_profile_picture`,
                                   `has_highlight_reels`, `is_business`, `is_active`, `is_verified`, `is_private`,
                                   `is_blocked`, `added`)
  VALUES (NEW.id, NEW.username, NEW.full_name, NEW.biography, NEW.profile_pic_id, NEW.profile_pic_url,
          NEW.hd_profile_pic_url,
          NEW.follower_count, NEW.following_count, NEW.media_count, NEW.usertags_count, NEW.following_tag_count,
          NEW.external_url,
          NEW.reel_auto_archive, NEW.has_biography_translation, NEW.has_anonymous_profile_picture,
          NEW.has_highlight_reels,
          NEW.is_business, NEW.is_active, NEW.is_verified, NEW.is_private, NEW.is_blocked, now());
END;

所以我有一些问题:

  1. 任何改进写作速度以保存历史的变体?我尝试通过LOAD DATA LOCAL INFILE,而不是触发 - 没有速度改进。
  2. 使用较少数据量保存历史记录的任何变体?例如,我想我可以运行一些外部脚本,检查user_history数据并为相同的值设置NULL?我尝试使用另一个触发器进行保存 - 更大,在写入之前比较每个值并仅写入更改的值 - 但它的执行时间很长。或者将数据差异(reuseble)保存到db的更好的变体?
mysql sql database optimization bigdata
1个回答
0
投票
  • 将计数器移动到并行表。将这些分开也将加速UPDATE。 “UPDATE”的内部处理涉及构建整个行的副本,以防某些其他连接访问同一行。
  • 此外,不要记录它们的历史。我猜大多数“更新”都在这个领域。
  • 将所有has_%is_%标志组合成单个SETTINYINT UNSIGNED(最多8个,或SMALLINT UNSIGNED最多16个)。
  • 没有has标志 - 当你需要检查“有”时,只需使用LEFT JOINEXISTS
  • 制作is_%标志(可能还有其他列)NOT NULL。一般来说,你应该有意识地决定NULL是否对业务逻辑有意义,而不是简单地将所有列都设为NULLable

(我的建议适用于所有版本的MySQL和MariaDB。)

© www.soinside.com 2019 - 2024. All rights reserved.