我有4个表的简单数据库。表Results
有18列。其中3个是外键。我试图用这段代码获得所有结果的数量(大约800k):
#I @"..\packages\SQLProvider.1.1.3\lib"
#r "FSharp.Data.SqlProvider.dll"
open FSharp.Data.Sql
let [<Literal>] ConnectionStringmdf = @"Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=C:\Users\Me\Desktop\myDb.mdf;Integrated Security=True;Connect Timeout=10"
type Sqlmdf = SqlDataProvider<
ConnectionString = ConnectionStringmdf,
DatabaseVendor = Common.DatabaseProviderTypes.MSSQLSERVER,
IndividualsAmount = 1000,
UseOptionTypes = true,
CaseSensitivityChange = Common.CaseSensitivityChange.ORIGINAL
>
let dbm = Sqlmdf.GetDataContext()
printfn "Results count:\t %i" (dbm.Dbo.Results |> Seq.length )
在一个表格中记录记录大约需要40秒。
为什么这么慢?我究竟做错了什么?
答案 0 :(得分:4)
SqlDataProvider返回的类型实现了IQueryable,这意味着您可以编写查询表达式或使用Queryable.Count
open System.Linq
dbm.Dbo.Results |> Queryable.Count
或
query { for it in dbm.Dbo.Results do
count
}
答案 1 :(得分:2)
您应该直接在表上执行查询,让服务器将结果返回给您。例如,我实时获得了8M行数:
type dbSchema = SqlDataConnection<connectionString1>
let dbx = dbSchema.GetDataContext()
dbx.DataContext.ObjectTrackingEnabled <- false
dbx.DataContext.CommandTimeout <- 60
let table1 = dbx.MyTable
table1.Count()
//val it : int = 7189765
您也可以将其包装成查询。
这是一个查询版本,(除非sqlprovider不做计数)也应该在另一个TP上工作。再一次,速度几乎是不稳定的。
query { for row in table1 do
select row
count
}
我使用SqlDataProvider
测试了相同的结果。如有必要,请打开System.Linq
命名空间以访问.Count()
扩展功能。