Im8*_*m89 10 scala compiled-query slick
我正在寻找有关已编译查询的执行的详细说明.我无法理解它们只是编译一次以及它们使用背后的优势
cvo*_*ogt 14
假设这个问题与使用有关,而不是编译查询的内部实现,这是我的答案:
当您编写Slick查询时,Slick实际上会在内部为所有涉及的表达式创建一个数据结构 - 一个抽象语法树(AST).当您想要运行此查询时,Slick将获取数据结构并将其转换(或换句话说编译)为SQL字符串.这可能是一个相当耗时的过程,比在DB上实际执行快速SQL查询需要更多的时间.理想情况下,每次查询需要执行时,我们都不应该对SQL进行这种转换.但是如何避免呢?通过缓存已翻译/编译的SQL查询.
Slick可以做的事情就像第一次编译它并在下次缓存它.但它没有,因为这使得用户更难以推理Slick的执行时间,因为相同的代码将在第一次变慢,但之后会更快.(Slick还需要在第二次运行时识别查询并在某个内部缓存中查找SQL,这会使实现复杂化).
因此Slick每次都会编译查询,除非你明确地缓存它.这使得行为非常可预测并最终更容易.要对其进行缓存,您需要使用Compiled结果并将其存储在下次需要查询时不会重新计算的位置.所以使用deflike def q1 = Compiled(...)并没有多大意义,因为它每次都会编译它.它应该是一个val或lazy val.此外,您可能不希望将该val放入多次实例化的类中.一个好的地方是val在顶级Scala单例中object,它只计算一次并保留JVM的实时时间.
所以换句话说,Compiled没有什么神奇之处.它只允许您显式触发Slick的Scala-to-SQL编译并返回包含SQL的值.重要的是,这允许与实际执行查询分开触发编译,这允许您编译一次,但多次运行它.
的优势很容易解释:查询编译需要时间,无论是在光滑和数据库服务器.如果多次执行相同的查询,则只编译一次更快.
Slick需要将带有集合操作的AST编译成SQL语句.(实际上,如果没有编译查询,你必须首先构建 AST,但与编译时相比,这非常快.)
数据库服务器必须为查询构建执行计划.这意味着解析查询,将其转换为本机数据库操作,并根据数据布局(例如,使用哪个索引)查找优化.即使您不在Slick中使用编译查询,只需使用绑定变量,也可以避免使用此部分,以便始终为不同的参数集获取相同的SQL代码.数据库服务器保留最近使用/编译的执行计划的缓存,因此只要SQL语句相同,执行计划就只是哈希查找,不需要再次计算.Slick依赖于这种缓存.Slick没有直接与数据库服务器通信以重用旧查询.
至于如何实现它们,以相同的方式处理流/非流和编译/应用/即席查询有一些额外的复杂性,但有趣的切入点是Compiled:
implicit def function1IsCompilable[A , B <: Rep[_], P, U](implicit ashape: Shape[ColumnsShapeLevel, A, P, A], pshape: Shape[ColumnsShapeLevel, P, P, _], bexe: Executable[B, U]): Compilable[A => B, CompiledFunction[A => B, A , P, B, U]] = new Compilable[A => B, CompiledFunction[A => B, A, P, B, U]] {
def compiled(raw: A => B, profile: BasicProfile) =
new CompiledFunction[A => B, A, P, B, U](raw, identity[A => B], pshape.asInstanceOf[Shape[ColumnsShapeLevel, P, P, A]], profile)
}
Run Code Online (Sandbox Code Playgroud)
这Compilable为每个人提供了一个隐含的对象Function.对于灵魂2至22的类似方法是自动生成的.因为个别参数只需要a Shape,所以它们也可以是嵌套元组,HLists或任何自定义类型.(我们仍然为所有函数arities提供抽象,因为它在语法上更方便地编写,比如a,而Function10不是Function1a Tuple10作为其参数.)
有一种方法Shape只存在以支持编译函数:
/** Build a packed representation containing QueryParameters that can extract
* data from the unpacked representation later.
* This method is not available for shapes where Mixed and Unpacked are
* different types. */
def buildParams(extract: Any => Unpacked): Packed
Run Code Online (Sandbox Code Playgroud)
通过此方法构建的"packed"表示可以生成包含QueryParameter具有正确类型的节点的AST .在编译期间,它们与其他文字处理相同,但实际值未知.提取器从identity顶层开始,并根据需要进行细化以提取记录元素.例如,如果你有一个Tuple2参数,AST最终会有两个QueryParameter节点知道如何在以后提取元组的第一个和第二个参数.
稍后是应用编译查询的时间点.执行这样的AppliedCompiledFunction使用预编译的SQL语句(或在第一次使用它时动态编译它)并通过提取器线程化参数值来填充语句参数.
| 归档时间: |
|
| 查看次数: |
2231 次 |
| 最近记录: |