如何针对特定查询优化表?

时间:2008-09-26 01:13:07

标签: sql database-design

  1. 您使用哪些模式来确定频繁查询?
  2. 如何选择优化因子?
  3. 可以做出哪些类型的更改?

9 个答案:

答案 0 :(得分:12)

这是一个很好的问题,如果相当宽泛(并且没有更糟糕的那样) 如果我了解你,那么你问的是如何从头开始攻击优化问题。

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

另一方面......

确定频繁查询

记录会让您经常查询 如果您正在使用某种数据访问层,那么添加代码来记录所有查询可能很简单 记录执行查询的时间以及每个查询所花费的时间也是一个好主意。这可以让您了解问题所在 此外,询问用户哪些位烦恼他们。如果缓慢的响应不会惹恼用户,那么无关紧要。

选择优化因子?

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

可以做出哪些改变?

您特别询问有关优化表格的信息 以下是您可以寻找的一些内容:

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

您可能也想my post on this

答案 1 :(得分:1)

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

如果我们谈论的是SQL Server:

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

答案 2 :(得分:1)

如果不知道你在谈论哪个系统,那很难回答。

在Oracle中,例如,企业管理器允许您查看哪些查询占用时间最多,让您比较不同的执行配置文件,并允许您在一段时间内分析查询,以便您不添加索引。以牺牲您运行的每一个查询为代价来帮助查询。

答案 3 :(得分:0)

  1. 对于MySQL,有一个名为log slow queries
  2. 的功能

    其余的数据取决于您拥有的数据类型以及设置方式。

答案 4 :(得分:0)

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

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

更具体的问题肯定能为您提供更好的答案。

答案 5 :(得分:0)

如果主要读取您的表,请在表中放置聚簇索引。

答案 6 :(得分:0)

我的经验主要是早期的DB2和一小部分Oracle。

如果你的DBMS有任何好处,它将能够收集特定查询的统计数据并解释它用于提取数据的计划。

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

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

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

select date from x where diskusage > 90

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

真正智能的DBMS'也可以解释你应该做些什么来提高性能(在这种情况下在diskusage上添加一个索引)。

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

答案 7 :(得分:0)

关于PKs和FKs的指数和一件总能帮助PARTITIONING ...

的事情

答案 8 :(得分:0)

<强> 1。您用来确定频繁查询的模式有哪些?

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

<强> 2。如何选择优化因子?

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

是否会更新以及更新发生在哪些字段? 它是否有低基数的列?

值得编制索引吗? (如果通过索引访问,可以减慢非常小的表)

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

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

第3。可以做出哪些类型的更改?

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

- 规范化/反规范化可以根据表的用法改善性能。我几乎总是规范化,然后只有当我能够以其他实际方式使查询更快时才能进行规范化。对查询进行非规范化的一种很好的方法,当你的情况允许时,就是保持真实表的规范化并创建一个带有物化视图的非规范化“表”。

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

- 使用索引组织表。

- 分区和子分区表和索引

- 使用存储过程减少应用程序的往返次数,提高安全性并启用查询优化,而不会影响用户。

- 如果合适,在内存中固定表格(访问量很大,相当小)

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

.....这个名单还在继续。 =)

希望这对你有所帮助。