F# 查询表达式是否具有与本机 SQL 相同的性能?
Do F# Query Expressions have same performance as Native SQL?
我注意到的 F# 查询表达式示例看起来好像它们在进行计算之前获取了 table 的全部内容。这似乎比原生 SQL 效率低。或者性能应该一样吗
// A query expression.
let query1 =
query {
for customer in db.Customers do
select customer
}
F# 查询表达式非常智能。除了使用引号(类似于 System.Linq.Expressions
)将代码转换为 SQL 之外,我不完全理解它们是如何工作的。 ORM 有 measurable overhead,原始查询会更快,但它们能够生成优化查询
给定这些模型和 ef-core 上下文
[<CLIMutable>] type Address = { Id: int; City: string; Country: string }
[<CLIMutable>] type Person = { Id: int; Name: string; Age: int; Address: Address }
type PeopleContext() =
inherit DbContext()
[<FSharp.Core.DefaultValue>]
val mutable _people : DbSet<Person>
member db.People
with get () = db._people
and set value = db._people <- value
override _.OnConfiguring options =
options.UseSqlite("Data source=db.db3") |> ignore
我创建了这个查询
query {
for person in ctx.People do
where (person.Age > 21)
select person.Address.City
take 1
} |> Seq.toArray |> printfn "%A"
翻译成这个 sql
SELECT "a"."City"
FROM (
SELECT "p"."AddressId"
FROM "People" AS "p"
WHERE "p"."Age" > 21
LIMIT @__p_0
) AS "t"
我注意到的 F# 查询表达式示例看起来好像它们在进行计算之前获取了 table 的全部内容。这似乎比原生 SQL 效率低。或者性能应该一样吗
// A query expression.
let query1 =
query {
for customer in db.Customers do
select customer
}
F# 查询表达式非常智能。除了使用引号(类似于 System.Linq.Expressions
)将代码转换为 SQL 之外,我不完全理解它们是如何工作的。 ORM 有 measurable overhead,原始查询会更快,但它们能够生成优化查询
给定这些模型和 ef-core 上下文
[<CLIMutable>] type Address = { Id: int; City: string; Country: string }
[<CLIMutable>] type Person = { Id: int; Name: string; Age: int; Address: Address }
type PeopleContext() =
inherit DbContext()
[<FSharp.Core.DefaultValue>]
val mutable _people : DbSet<Person>
member db.People
with get () = db._people
and set value = db._people <- value
override _.OnConfiguring options =
options.UseSqlite("Data source=db.db3") |> ignore
我创建了这个查询
query {
for person in ctx.People do
where (person.Age > 21)
select person.Address.City
take 1
} |> Seq.toArray |> printfn "%A"
翻译成这个 sql
SELECT "a"."City"
FROM (
SELECT "p"."AddressId"
FROM "People" AS "p"
WHERE "p"."Age" > 21
LIMIT @__p_0
) AS "t"