FSharp.Data.SqlProvider est lent

J'ai simple DB avec 4 tables. Les Results tableau ont 18 colonnes. 3 d'entre eux sont des foreign keys. J'essaie d'get le nombre de tous les résultats (environ 800k) avec ce code:

 #I @"..\packages\SQLProvider.1.1.3\lib" #r "FSharp.Data.SqlProvider.dll" open FSharp.Data.Sql let [<Literal>] ConnectionSsortingngmdf = @"Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=C:\Users\Me\Desktop\myDb.mdf;Integrated Security=True;Connect Timeout=10" type Sqlmdf = SqlDataProvider< ConnectionSsortingng = ConnectionSsortingngmdf, 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 ) 

Il faut environ 40 secondes pour get le nombre d'loggings dans une table.

Pourquoi est-ce si lent? Qu'est-ce que je fais mal?

Les types returnnés par SqlDataProvider implémentent IQueryable ce qui signifie que vous pouvez écrire une expression de requête ou utiliser Queryable.Count

 open System.Linq dbm.Dbo.Results |> Queryable.Count 

ou

 query { for it in dbm.Dbo.Results do count } 

Vous devez simplement exécuter la requête directement sur la table et requestr au server de vous renvoyer le résultat. Par exemple, j'obtiens un nombre de lignes de 8M instantanément:

 type dbSchema = SqlDataConnection<connectionSsortingng1> let dbx = dbSchema.GetDataContext() dbx.DataContext.ObjectTrackingEnabled <- false dbx.DataContext.CommandTimeout <- 60 let table1 = dbx.MyTable table1.Count() //val it : int = 7189765 

Vous pouvez également l'inclure dans une requête.

Voici une version de requête, qui (à less que sqlprovider ne count pas) devrait aussi fonctionner sur l'autre TP. Encore une fois, la vitesse est presque instantanée.

 query { for row in table1 do select row count } 

J'ai testé la même chose avec SqlDataProvider avec des résultats similaires. Ouvrez l'espace de noms System.Linq pour accéder à la fonction d'extension .Count() si nécessaire.