【问题标题】:Which approach is better in terms of database performance - one table group by operations or multiple tables serializable transaction?哪种方法在数据库性能方面更好 - 一个表组按操作或多个表可序列化事务?
【发布时间】:2017-11-03 11:59:42
【问题描述】:

我正在开发一个基于 SQL 数据库的预订系统(对特定数据库没有限制)。

架构:

工作流程:

现在我正在使用一个特殊的“actual_reservations”视图,该视图基于带有过滤逻辑的自定义分组来识别实际放置的预订,例如:

CREATE VIEW `reserv-io`.`actual_reserved_resources` AS
  SELECT
    `r`.`id`,
    `a`.`resource_id`,
    `a`.`type_id`,
    `a`.`status_id`,
    `a`.`reservation_start`,
    `a`.`reservation_end`
  FROM `reserv-io`.`actions` `a`
    JOIN (SELECT
            `r`.`id`      `id`,
            MAX(`a`.`id`) `action_id`
          FROM `reserv-io`.`reservations` `r`
            JOIN `reserv-io`.`actions` `a` ON `r`.`id` = `a`.`reservation_id`
          WHERE (`r`.`id` NOT IN
                 (SELECT `r`.`id` `id`
                  FROM `reserv-io`.`reservations` `r`
                    JOIN `reserv-io`.`actions` `a` ON `r`.`id` = `a`.`reservation_id`
                  WHERE (`a`.`status_id` IN
                         (SELECT `id`
                          FROM `reserv-io`.`reservation_statuses`
                          WHERE `name` = 'Canceled')))
                 AND `a`.`status_id` IN
                     (SELECT `id`
                      FROM `reserv-io`.`reservation_statuses`
                      WHERE `name` = 'Approved' OR `name` = 'Accepted'))
          GROUP BY `r`.`id`) `b`
      ON `a`.`id` = `b`.`action_id`
    JOIN `reserv-io`.`reservations` `r` ON `r`.`id` = `a`.`reservation_id`;

并确定是否与其他保留有任何重叠,程序如下:

CREATE PROCEDURE HAS_OVERLAPPING_RESERVATION_WITH_TYPE_SELF_CHECK(
  IN  RESERVATION      BIGINT,
  IN  RESOURCE         INT,
  IN  RESERVATION_TYPE INT,
  IN  STARTS_AT        DATETIME,
  IN  ENDS_AT          DATETIME,
  OUT RESULT           BIT)
  BEGIN
    SELECT CASE WHEN EXISTS(
        SELECT *
        FROM actual_reserved_resources r
        WHERE r.resource_id = RESOURCE
              AND r.type_id = RESERVATION_TYPE
              AND r.reservation_start < ENDS_AT
              AND r.reservation_end > STARTS_AT
              AND r.id <> RESERVATION)
      THEN TRUE
           ELSE FALSE END
    INTO RESULT;
  END$$

我已经在 'actions' 表上有了很好的索引,但我不确定我使用单个表处理与预订相关的所有操作的方法是否真正具有可扩展性。我听说过一种方法,我将所有待处理和实际批准的预订存储到单独的表中,然后手动将它们同步到事务中。

我的问题是关于您的 POV 中的哪种方法在数据库性能、可扩展性和良好的数据设计方面更好?

【问题讨论】:

    标签: sql database-design architecture database-performance


    【解决方案1】:

    我建议:

    • 不要把这里任何人的回答视为理所当然;而是使用真实数据进行基准测试,以衡量实际性能。

    • 无论答案是什么,它都没有你担心的那么重要。它肯定不会区分可扩展系统和不可扩展系统。

    • 如果事实证明将某种记录分为待处理和已批准记录确实有任何优点,您将能够通过 行分区 来实现它(查找) 这样您就可以将所有内容保存在一个逻辑表中,并避免以性能的名义弄乱您的架构。

    【讨论】:

      【解决方案2】:

      您没有提及数据集的大小或运行查询的系统的大小。在您获得大型数据集之前,它可能不会有太大的不同。我对大型数据集的个人经验是,当系统开始交换到磁盘而不是将内容保存在内存中时,跨两个以上表的连接可能会执行得很慢。几年前,在 Oracle 上,我有一个特定的查询需要涉及六个表。在一个查询中,运行了大约六个小时。作为一次涉及两个表的单个查询,需要 15 分钟。我在 MySQL 上有一个不同的查询,它触及了一些表。将其分解为更小的查询将总运行时间从大约 7 小时减少到 7 分钟。

      【讨论】:

      • 好的,我应该在发布这个问题时指定它。数据大小 - 最多 10000 个用户,每年最多 1000 个预订,大约5 项操作每年为我们提供 5000 万条记录
      猜你喜欢
      • 1970-01-01
      • 2017-04-08
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 2017-03-01
      • 2018-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多