FSharp.Data.SqlProvider很慢

时间:2017-07-12 11:31:50

标签: sql-server f# type-providers f#-interactive

我有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秒。

为什么这么慢?我究竟做错了什么?

2 个答案:

答案 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()扩展功能。