概述

AutoTune 是一项 Ebean 功能,它可以根据应用程序的分析结果自动调优 ORM 查询。分析确定应用程序使用了对象图的哪一部分,并提供一个经过优化的查询,该查询可用于调优 ORM 查询的 select()fetch() 部分。

AutoTune

使用分析进行自动查询调优

原点

ORM 查询有一个 原点,它有一个哈希键,如 wpbnw.BQejAt.Bzpaqe,它由 3 部分组成 - 查询 Bean 类型和查询类型、执行查询的直接方法和调用堆栈。

原点哈希包括调用堆栈,以便针对不同的用例调优单个查询。例如,可以通过 3 个不同的调用堆栈调用按 Id 查找客户的查询,并针对每种情况进行调优,因此一个可能仅获取客户姓名,第二个用例可能获取一些客户详细信息,第三个用例可能获取一些客户详细信息以及客户送货地址和客户账单地址。

通过这种方式,AutoTune 可以针对多个用例调优单个查询,而这在使用手动显式查询调优时不容易做到。

分析

当分析调优开启时,它将收集 对象图使用情况(应用程序使用的路径/属性),并将对象图使用情况关联回 原点。合并使用的路径/属性将提供调优后的查询,该查询实际上是 select 和 fetch 子句。

分析设置由 AutoTuneConfig 配置,但默认设置预计适用于大多数情况,你通常只需使用默认设置开启分析。

  • profilingBase = 5:这意味着将分析原点的第一个 5 个查询
  • profilingRate = 0.01:在分析原点的第一个 5 个查询之后,将分析 1% 的查询
  • garbageCollectionWait = 100:在关闭时触发 GC 并等待 100 毫秒以收集分析信息
  • skipCollectionOnShutdown = false:将其设置为 true 以跳过 GC 并等待关闭
  • profilingFile = "ebean-profiling":这是分析输出的文件名

开启分析

ebean.autotune.profiling=true
  
ServerConfig serverConfig = ...

// turn on profiling
serverConfig.getAutoTuneConfig().setProfiling(true);

分析文件:ebean-profiling.xml

如果已启用分析,则在关闭时,收集的分析信息将输出到分析文件中。分析文件包含 3 个部分,分别是

  • profileNew:没有先前的自动调整调整项的新分析条目
  • profileDiff:分析查询与现有的自动调整调整项不同的条目
  • profileEmpty:没有收集分析信息的现有自动调整调整项的原始键

profileNew

通常,您可以将 profileNew 条目从分析转移到自动调整文件中。它们代表新条目,可能是由于新代码/查询或由于原始点哈希码已更改。

profileDiff

这些条目表示在将分析查询与现有调整查询进行比较时存在差异。例如,代码更改,以便现在使用附加路径/属性。

对于 profileDiff 条目,detail 包含分析建议的查询,original 包含现有的调整查询。

示例

在下面的示例中,diff 条目向我们展示了对于此原始点,应用程序现在还使用 order.shipDate 和 customer.name

<profileDiff>
  <origin key="h_zOh.wpbnw.DJ7cI3" beanType="org.example.domain.Order"
          detail="select (shipDate,orderDate)  fetch customer (id,name) "
          original="select (orderDate)  fetch customer (id) ">
    <callStack>org.example.domain.finder.OrderFinder.byStatus(OrderFinder.java:38)
      org.example.domain.finder.OrderFinderTest.testOther(OrderFinderTest.java:51)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    </callStack>
  </origin>
</profileDiff>

profileEmpty

profileEmpty 条目是没有收集分析信息的调整原始点。如果应用程序的相关部分没有运行,或者关联的哈希不再有效(因为代码已更改/删除),则会显示 profile empty 条目。

示例
<profileEmpty>
  <origin key="wpbnw.BQejAr.Bzpaqe"/>
  <origin key="wpbnw.BQejAr.CEn3iT"/>
</profileEmpty>

调整

当启用调整时,在 Ebean 启动时,将读取调整文件,加载调整查询及其关联的原始键。

可调整的 ORM 查询获取其原始键并查找关联的调整查询。如果为原始键找到匹配的调整查询,则将查询调整应用于查询。

select() / fetch()

此查询调整有效地将调整查询中的 select/fetch 子句应用于查询。如果查询已经包含调整查询中没有的一些 fetch 子句,则目前不会删除这些子句。

JPA FetchGroups

如果您熟悉 JPA/JDO FetchGroups,那么您可以将此查询调优粗略地等同于应用 FetchGroup。但是,应该注意的是,Ebean 永远不会生成 SQL 笛卡尔积,始终遵守 firstRows/maxRows,并且没有最大深度限制(没有 maxDepth)——Ebean 的选择/获取是防弹的,并且没有隐藏的限制/陷阱/陷阱。

开启调优

ebean.autotune.queryTuning=true

# optionally specify the location of ebean-autotune.xml
#ebean.autotune.queryTuningFile=ebean-autotune.xml
  
ServerConfig serverConfig = ...

AutoTuneConfig autoTuneConfig = serverConfig.getAutoTuneConfig();

// turn on query tuning
autoTuneConfig.setQueryTuning(true);

// Optional: specify full path to ebean-autotune.xml
// autoTuneConfig.setQueryTuningFile(" ...some file path... ");

调优文件:ebean-autotune.xml

ebean-autotune.xml 调优文件包含一个源列表及其调优查询。

示例
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<autotune xmlns="http://ebean-orm.github.io/xml/ns/autotune">
  <origin key="wpbnw.BQejAr.Bzpaqe" beanType="org.example.domain.Order"
          detail="select (orderDate,shipDate,status)  fetch details (id,orderQty)"
          original="select ">
    <callStack>org.example.domain.finder.OrderFinder.byStatus(OrderFinder.java:38)
      org.example.domain.finder.OrderFinderTest.test(OrderFinderTest.java:20)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    </callStack>
  </origin>
  <origin key="wpbnw.BQejAr.CEn3iT" beanType="org.example.domain.Order"
          detail="select (orderDate,shipDate)  fetch customer (id,name) "
          original="select ">
    <callStack>org.example.domain.finder.OrderFinder.byStatus(OrderFinder.java:38)
      org.example.domain.finder.OrderFinderTest.testOther(OrderFinderTest.java:51)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    </callStack>
  </origin>
</autotune>
填充 ebean-autotune.xml

目前,您通过从分析文件中剪切粘贴手动填充 ebean-autotune.xml,但将在关闭时将分析合并到调优文件中的选项进行调查。