【问题标题】:How do you optimize tables for specific queries?您如何针对特定查询优化表?
【发布时间】:2010-09-13 07:51:00
【问题描述】:
  1. 您使用哪些模式来确定频繁查询?
  2. 如何选择优化因子?
  3. 可以进行哪些类型的更改?

【问题讨论】:

  • 我使用的是 postgresql 8.2

标签: sql database-design


【解决方案1】:

这是一个很好的问题,虽然范围很广(而且没有更糟)。
如果我理解你,那么你问的是如何从头开始解决优化问题。

要问的第一个问题是:“是否存在性能问题?”
如果没有问题,那么你就完成了。这种情况经常发生。不错。

另一方面...

确定频繁查询

日志记录将为您提供经常查询的信息。
如果您使用某种数据访问层,那么添加代码来记录所有查询可能很简单。
记录查询的执行时间以及每个查询需要多长时间也是一个好主意。这可以让您了解问题所在。
此外,询问用户哪些内容会惹恼他们。如果缓慢的响应不会惹恼用户,那也没关系。

选择优化因素?

(我可能误解了这部分问题) 您正在寻找查询/响应时间中的任何模式。
这些通常是对大型表的查询或在单个查询中连接多个表的查询。 ...但如果您记录响应时间,则可以按照这些时间进行指导。

可以做出哪些改变?

您是在专门询问优化表格的问题。
以下是您可以寻找的一些内容:

  • 非规范化。这将几个表合并到一个更宽的表中,因此您不必将多个表连接在一起,而只需读取一个表即可。这是一种非常常见且功能强大的技术。注意。我建议保留原始规范化表并另外构建非规范化表 - 这样,您就不会丢弃任何东西。如何保持最新是另一个问题。您可以在基础表上使用触发器,或定期运行刷新过程。
  • 标准化。这通常不被认为是一个优化过程,但有两种情况:
    • 更新。规范化使更新更快,因为每次更新都是最小的(您正在更新最小的 - 就列和行而言 - 可能的表。这几乎就是规范化的定义。
    • 查询非规范化表以获取存在于更小(更少行)表上的信息可能会导致问题。在这种情况下,存储规范化表和非规范化表(见上文)。
  • 水平分区。这意味着通过将一些行放在另一个相同的表中来使表更小。一个常见的用例是在表 ThisMonthSales 中包含本月的所有行,在表 OldSales 中包含所有较旧的行,其中两个表具有相同的架构。如果大多数查询都是针对最近的数据,则此策略可能意味着 99% 的查询只查看 1% 的数据 - 巨大的性能优势。
  • 垂直分区。这是从表中切出字段并将它们放入一个新表中,该表通过主键连接回主表。这对于非常宽的表格(例如具有数十个字段)很有用,并且在表格填充稀疏的情况下可能会有所帮助。
  • 指标。我不确定您的问题是否涵盖这些,但是关于使用 indeces 的 SO 还有很多其他答案。为索引查找案例的一个好方法是:查找慢查询。查看查询计划并找到表扫描。该表上的索引字段,以便删除表扫描。如果需要,我可以就此写更多 - 发表评论。

您可能还喜欢my post on this。

【讨论】:

    【解决方案2】:

    如果不知道您说的是哪个系统,这很难回答。

    例如,在 Oracle 中,企业管理器可以让您查看哪些查询占用的时间最多,让您比较不同的执行配置文件,并让您在一段时间内分析查询,这样您就不会添加一个以牺牲您运行的所有其他查询为代价来帮助一个查询。

    【讨论】:

      【解决方案3】:

      你的问题有点含糊。哪个数据库平台?

      如果我们谈论的是 SQL Server:

      1. 使用动态管理视图。使用 SQL 事件探查器。安装 SP2 和性能仪表板报告。
      2. 在确定成本最高的查询(即运行次数 x 一次查询的成本)后,检查它们的执行计划,并查看所涉及的表的大小,以及它们主要是读取还是写入,或者混合使用两者都有。
      3. 如果系统在您的完全控制之下(应用程序和数据库),您通常可以重写格式错误的查询(很常见),例如通常可以重写为的深度相关子查询派生表加入一点想法。否则,您可以选择创建覆盖非聚集索引并确保统计信息保持最新。

      【讨论】:

        【解决方案4】:
        1. 对于 MySQL,有一个名为 log slow queries 的功能

        其余的取决于你拥有什么样的数据以及它是如何设置的。

        【讨论】:

          【解决方案5】:

          在 SQL Server 中,您可以使用跟踪来了解查询的执行情况。使用 ctrl + k 或 l

          例如,如果您看到在具有大量记录的表中发生全表扫描,那么它可能不是一个好的查询。

          一个更具体的问题肯定会给你带来更好的答案。

          【讨论】:

            【解决方案6】:

            如果您的表主要被读取,请在表上放置一个聚集索引。

            【讨论】:

              【解决方案7】:

              我的经验主要是早期的 DB2 和少量的 Oracle。

              如果您的 DBMS 好用,它将能够收集特定查询的统计信息并解释它用于提取数据的计划。

              例如,如果您有一个包含两列(日期和磁盘使用)的表 (x),并且只有一个日期索引,则查询:

              select diskusage from x where date = '2008-01-01'
              

              将非常有效,因为它可以使用索引。另一方面,查询

              select date from x where diskusage > 90
              

              不会那么高效。在前一种情况下,“解释计划”会告诉您它可以使用索引。在后者中,它会说它必须进行表扫描才能获取行(这基本上是查看每一行以查看是否匹配)。

              真正智能的 DBMS 还可以解释您应该如何提高性能(在这种情况下,在磁盘使用上添加索引)。

              至于如何查看正在运行的查询,您可以从 DBMS 收集(如果允许)或强制每个人通过存储过程进行查询,以便 DBA 控制查询是什么 - 这是他们的作业,保持数据库高效运行。

              【讨论】:

                【解决方案8】:

                关于 PK 和 FK 的索引以及总是有助于分区的一件事......

                【讨论】:

                  【解决方案9】:

                  1.您使用什么模式来确定频繁查询?

                  取决于您处理数据库的级别。如果您是 DBA 或有权使用这些工具,那么像 Oracle 之类的数据库允许您在指定的时间段内运行作业并生成统计信息/报告。如果您是针对数据库编写应用程序的开发人员,您可以在您的应用程序中进行性能分析。

                  2。如何选择优化因子?

                  我尝试大致了解该表的使用方式及其包含的数据。我会回答以下问题。

                  它会被大量更新吗?更新发生在哪些领域? 它有低基数的列吗?

                  值得索引吗? (如果通过索引访问,非常小的表可能会变慢)

                  让它运行得更快值得多少维护/头痛?

                  更新/插入与查询的比率?

                  等等

                  3.可以进行哪些类型的更改?

                  -- 如果使用 Oracle,请保持最新的统计信息! =)

                  -- Normalization/De-Normalization 中的任何一个都可以根据表的使用情况来提高性能。我几乎总是规范化,然后只有当我无法以其他实际方式使查询更快时才会去规范化。对查询进行非规范化以及在您的情况允许时保持真实表规范化并创建具有物化视图的非规范化“表”的好方法。

                  -- 明智地索引。太多可能在许多层面上都不好。只要您不经常更新列并且该列的基数较低,Oracle 中的位图索引就很棒。

                  -- 使用索引组织的表。

                  -- 分区和子分区表和索引

                  -- 使用存储过程减少应用程序的往返行程,提高安全性,并在不影响用户的情况下启用查询优化。

                  -- 适当时将表固定在内存中(访问很多且相当小)

                  -- 索引和表数据库文件之间的设备分区。

                  .....列表还在继续。 =)

                  希望这对你有帮助。

                  【讨论】:

                    猜你喜欢
                    • 2021-01-30
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-08-03
                    • 2023-01-12
                    • 1970-01-01
                    相关资源
                    最近更新 更多