微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

scala – 如何在光滑的编译查询实际工作?

我正在寻找有关已编译查询的执行的详细说明.我无法理解它们只是编译一次以及它们使用背后的优势

解决方法

假设这个问题是关于用法,而不是编译查询的内部实现,这是我的答案:

当您编写Slick查询时,Slick实际上会在内部为所有涉及的表达式创建一个数据结构 – 一个抽象语法树(AST).当您想要运行此查询时,Slick将获取数据结构并将其转换(或换句话说编译)为sql字符串.这可能是一个相当耗时的过程,比在DB上实际执行快速SQL查询需要更多的时间.因此,理想情况下,每次查询需要执行时,我们都不应该对sql进行此转换.但是如何避免呢?通过缓存已翻译/编译的SQL查询.

Slick可以做类似的事情,只在第一次编译它并在下次缓存它.但它没有,因为这使得用户更难以推理Slick的执行时间,因为相同的代码将在第一次变慢,但之后会更快. (Slick还需要在第二次运行时识别查询并在某些内部缓存中查找sql,这会使实现复杂化).

因此Slick每次都会编译查询,除非你明确地缓存它.这使得行为非常可预测并最终更容易.要缓存它,您需要使用Compiled并将结果存储在下次需要查询时不会重新计算的位置.所以使用像def q1 = Compiled(…)这样的def没有多大意义,因为它每次都会编译它.它应该是val或lazy val.此外,您可能不希望将该val放入多次实例化的类中.一个好的地方是顶级Scala单例对象中的val,它只计算一次并保留JVM的实时时间.

所以在其他方面,Compiled并没有什么神奇之处.它只允许您显式触发Slick的Scala-to-sql编译并返回包含sql的值.重要的是,这允许与实际执行查询分开触发编译,这允许您编译一次,但多次运行它.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐