Ratio optimizing LINQ queries in C #. NET

introduction

Π’ hoc articulum aliqua ipsum modi sunt considerari LINQ queries.
Hic etiam nonnullas accessiones ad codicem optimization relatas exhibemus LINQ queries.

Notum enim est, LINQLingua simplex et commoda est ad fontem quaerendum.

А LINQ ad SQL technologia pro accessu data in DBMS est. Hoc instrumentum validum est ad operandum cum notitia, in quibus queries construuntur per linguam declarativam, quae tunc convertetur SQL queries suggestum et servo datorum ad supplicium misit. In nobis, per DBMS intelligimus MS SQL Servo.

autem, LINQ queries non convertuntur in bene scripta sunt SQL queriesquam peritus DBA scribere potuit cum omnibus nuis optimization SQL queries:

  1. bene nexus (JOIN) et eventus eliquare (UBI)
  2. multis extenuatis in usus hospites et coetus conditionibus
  3. plures varietates repositoque conditionibus IN on ESTΠΈ NON IN', <> on EST
  4. intermedii eventus cautiones per tabulas temporales, CTE, mensa variabilium
  5. uti sententia (OPTIO) Cum mandatis ac mensa innuit cUM (...)
  6. usura indexed views ut medium ad tollendum redundans notitia lectionum in lectionibus

Pelagus perficientur bottlenecks inde SQL queries cum componendis LINQ queries Sunt;

  1. solidatio totius notitiae lectionis mechanismum in una petitione
  2. duplicando cuneos identicos codicis, qui postremo ducit notitias multiplices supervacuas legit
  3. - ET ΠΈ ORConiungens in implicatas conditiones, eo ducit quod optimizer, cum indices agrorum necessarios non-complicatos opportunos, postremo contra index fasciculorum incipit lustrare.INDEX SCAN) A coetibus conditionibus
  4. profunda nidificans subqueries facit parsing valde inconveniens SQL statements et analysis inquisitionis consilii ex parte tincidunt et DBA

Optimization modi

Nunc directe ad methodos optimization transeamus.

I) Additional indexing

Optimum est considerare filters in tabulis principalibus eligendis, quia saepissime tota quaestio circa unam vel duas tabulas principales aedificatur (applicationes-people-operationes) et cum norma conditionum (IsClosed, Canceled, Enabled, Status). Magni interest ut indices congruas ad exempla identified.

Haec solutio sensum praebet cum eligens hos agros signanter limitat redditus statuti quaesiti.

Exempli gratia, 500000 applicationes habemus. Sed applicationes activae tantum 2000 sunt. Tum index recte lectus nos salvabit INDEX SCAN in magna mensa, et permittet te cito datas eligere per indicem non glomeratum.

Item, defectus indices cognosci potest per suggerere ut consilia quaerendi parsing vel ratio colligendi visum mutant MS SQL Servo:

  1. sys.dm_db_missing_index_groups
  2. sys.dm_db_missing_index_group_stats
  3. sys.dm_db_missing_index_details

Omnis sententia data notitias continet de indicibus absentibus, exceptis indicibus localibus.

Attamen indices et cautiones saepe modi pugnandi consectaria male scripta sunt LINQ queries ΠΈ SQL queries.

Sicut acerbum vitae usum ostendit, saepe magni momenti est ad negotium conficiendum per certas notas certas notas. Quam ob rem petitiones graves saepe in curriculum vitae cum caching transferuntur.

Hoc partim iustificatur, quia usor recentissimas notitias non semper indiget et acceptabilis gradus est docilitatis interfaciei utentis.

Accessus hic solvendo negotium necessitates concedit, sed tandem ad systema informativum perficiendum solum solutiones problematum differendo redigit.

Memorabile quoque est in processu perquirendi indices necessarios addere, suggestiones MSSQL optimizatio falsa esse potest, etiam sub his condicionibus:

  1. si iam sunt indices cum simili copia agrorum
  2. si agri in mensa inscribi non possunt propter limitationem indexing (de quo fusius hic).

II) Merging attributa in unum novum attributum

Aliquando quidam campi ex una tabula, quae pro fundamento condicionum insunt, substitui possunt unum novum agrum inducendo.

Hoc imprimis valet de statu agrorum, qui plerumque vel mordicus vel integer in specie sunt.

exempli gratia:

IsClosed = 0 et Pax = 0 et enabled = 0 substituitur Status = 1.

Hoc est ubi attributum integrum Status introducitur ut hi status in schemate frequententur. Deinde haec nova passio recensetur.

Haec est fundamentalis solutio ad problema perficiendum, quia notitias accessus sine calculis superfluis.

III) Material ex visu

Donec in LINQ queries Mensae temporariae, CTEs, ac mensae variabiles directe adhiberi non possunt.

Sed alius modus est optimize pro hac re - opiniones inscriptas.

Circulus conditio (exempli gratia supra) IsClosed = 0 et Pax = 0 et enabled = 0 (vel alias condiciones similes statuto) bene fit optio ut illis in sententia inspiciatur ut frustum notitiarum e magno statuto capiat.

Sed multae restrictiones sunt materialiter visum;

  1. uti subquisitionum, clausulae EST debet reponi utendo JOIN
  2. non uti sententias JUNCTIO, Omnes CONIUNCTIO, EXCEPTIO, INTERSECO
  3. Mensa innuit et clausulas uti non potes OPTIO
  4. nulla facultatem ad opus circuitus
  5. Impossibile est proponere notitias in una sententia ex diversis tabulis

Praestat autem meminisse verum beneficium utendi sententia indicente nonnisi effici posse eam in actu indicendo.

Sed cum sententiam inspicias, hi indices adhiberi non possunt, iisque expressis verbis uti oportet, notandum est CUM (NOEXPAND).

Cum in LINQ queries Impossibile est tabellam ambages definire, sic habes ut aliam repraesentationem efficias - "involucrum" sequentis formae;

CREATE VIEW ИМЯ_прСдставлСния AS SELECT * FROM MAT_VIEW WITH (NOEXPAND);

IV) Using munera mensa

Saepe in LINQ queries Ingentes stipites subqueriorum vel clausorum utentes sententias cum structura multiplici utentes quaestionem finalem faciunt cum structura admodum implicata et suboptimali executione.

Key Beneficia usus Tabula functionum LINQ queries:

  1. Facultas, ut in opinionibus, utendum et determinatum ut obiectum, sed praefinitum parametri initus transire potes;
    EX MUNERE(@param1, @param2 ...)
    Quam ob rem flexibilis notitia sampling effici potest
  2. In casu utendi functionis mensa, nullae sunt tam validae restrictiones ac in casu sententiae quae supra scriptae sunt;
    1. Mensa innuit:
      per LINQ Non potes exprimere quibus indices adhibeantur et indices notitiarum segregationis cum interrogatione determinanda sunt.
      sed habet has facultates.
      Cum munere, satis constantem exsecutionem interrogationis consilii consequi potes, ubi regulae ad operandum cum indicibus et notitiis segregandorum definiuntur.
    2. Munus utens permittit, prae visibus suprascriptis, impetrare;
      • universa notitia sampling ratione (etiam per ora sagi alterius)
      • varias notitias tabulas ducens
      • usum JUNCTIO ΠΈ EST

  3. offer OPTIO valde utile, cum opus est providere Concurrency control OPTION(MAXDOP N)ordo inquisitionis exsecutionis. Exempli gratia:
    • specificare potes coactus re-creationem interrogationis consilii OPTION (RECOMPILE)
    • specificare potes utrum consilium interrogationis compellere ut ordine certo in interrogatione utatur OPTION (ORDINE VIS)

    More details about OPTIO descriptus " hic.

  4. Usura angustissima et exquisitissima data scalpere;
    Non opus est magnas notitias in cella condere (ut fit cum sententiis memoratis), ex quibus etiamnum notitias per modulum eliquare debes.
    Exempli gratia, mensa est cuius colum UBI tria sunt agri (a, b, c).

    Placitum, omnes petitiones constantem habent conditionem a = 0 et b = 0.

    Sed petitio pro agro c variabilius.

    Fiat conditio a = 0 et b = 0 Re vera adiuvat nos ad mille monumenta circumscribere quae inde statuta sunt, sed condicio с contrahit lectio usque ad centum tabulas.

    Munus mensae hic fortasse optio melior.

    Praedictio etiam est functio mensae et temporis in execu- tione consistens.

exempla

Intueamur exemplum deducendi per interrogationes datorum in exemplum.

Est petitio LEGO, quae plures tabulas coniungit et una sententia utitur, in qua affiliatio inscriptionis inhibetur. EST) ad "Quaestiones operativas":

Request No. 1

(@p__linq__0 nvarchar(4000))SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Join2].[Object_Id] AS [Object_Id],
[Join2].[ObjectType_Id] AS [ObjectType_Id],
[Join2].[Name] AS [Name],
[Join2].[ExternalId] AS [ExternalId]
FROM [dbo].[Questions] AS [Extent1]
INNER JOIN (SELECT [Extent2].[Object_Id] AS [Object_Id],
[Extent2].[Question_Id] AS [Question_Id], [Extent3].[ExternalId] AS [ExternalId],
[Extent3].[ObjectType_Id] AS [ObjectType_Id], [Extent4].[Name] AS [Name]
FROM [dbo].[ObjectQuestions] AS [Extent2]
INNER JOIN [dbo].[Objects] AS [Extent3] ON [Extent2].[Object_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[ObjectTypes] AS [Extent4] 
ON [Extent3].[ObjectType_Id] = [Extent4].[Id] ) AS [Join2] 
ON [Extent1].[Id] = [Join2].[Question_Id]
WHERE ([Extent1].[AnswerId] IS NULL) AND (0 = [Extent1].[Exp]) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[OperativeQuestions] AS [Extent5]
WHERE (([Extent5].[Email] = @p__linq__0) OR (([Extent5].[Email] IS NULL) 
AND (@p__linq__0 IS NULL))) AND ([Extent5].[Id] = [Extent1].[Id])
));

Visum structuram magis implicatam habet: subqueriam coniungit et genus usus habet RECTUSquae omnino res satis intensiva est.

Specimen ab OperativeQuaestionum circiter decem milia monumentorum est.

Praecipua quaestio cum hac interrogatione est quod in commentariis ex interrogatione externa, quaestio interna exercetur in sententia [Operative] quae debet pro [Email] = @p__linq__0 sinat nos circumscribere output electionem (per EST) usque ad centum annales.

Et videri potest quod subquerius computare tabulas semel ab [Email] = @p__linq__0, et tunc haec duo centum monumenta cum questionibus Id coniungi debent, et quaesitum erit velociter.

Re vera omnium tabularum nexus sequentialis est: inhibita correspondentia quaestionum cum Id ab OperativeQuaestionum, et percolando electronicas.

Re quidem vera, petitio per omnia decem milia monumentorum Operativestionum laborat, sed solum notitia usurarum necessaria est per Email.

OperativeQuestions view text:

Request No. 2

 
CREATE VIEW [dbo].[OperativeQuestions]
AS
SELECT DISTINCT Q.Id, USR.email AS Email
FROM            [dbo].Questions AS Q INNER JOIN
                         [dbo].ProcessUserAccesses AS BPU ON BPU.ProcessId = CQ.Process_Id 
OUTER APPLY
                     (SELECT   1 AS HasNoObjects
                      WHERE   NOT EXISTS
                                    (SELECT   1
                                     FROM     [dbo].ObjectUserAccesses AS BOU
                                     WHERE   BOU.ProcessUserAccessId = BPU.[Id] AND BOU.[To] IS NULL)
) AS BO INNER JOIN
                         [dbo].Users AS USR ON USR.Id = BPU.UserId
WHERE        CQ.[Exp] = 0 AND CQ.AnswerId IS NULL AND BPU.[To] IS NULL 
AND (BO.HasNoObjects = 1 OR
              EXISTS (SELECT   1
                           FROM   [dbo].ObjectUserAccesses AS BOU INNER JOIN
                                      [dbo].ObjectQuestions AS QBO 
                                                  ON QBO.[Object_Id] =BOU.ObjectId
                               WHERE  BOU.ProcessUserAccessId = BPU.Id 
                               AND BOU.[To] IS NULL AND QBO.Question_Id = CQ.Id));

DbContext (EF Core 2)

public class QuestionsDbContext : DbContext
{
    //...
    public DbQuery<OperativeQuestion> OperativeQuestions { get; set; }
    //...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Query<OperativeQuestion>().ToView("OperativeQuestions");
    }
}

Coepi LINQ interrogatione

var businessObjectsData = await context
    .OperativeQuestions
    .Where(x => x.Email == Email)
    .Include(x => x.Question)
    .Select(x => x.Question)
    .SelectMany(x => x.ObjectQuestions,
                (x, bo) => new
                {
                    Id = x.Id,
                    ObjectId = bo.Object.Id,
                    ObjectTypeId = bo.Object.ObjectType.Id,
                    ObjectTypeName = bo.Object.ObjectType.Name,
                    ObjectExternalId = bo.Object.ExternalId
                })
    .ToListAsync();

In hoc casu particulari, solutionem huius quaestionis sine mutationibus infrastructuralibus consideramus, quin mensam separatam cum promptis effectibus (Β«Active QueriesΒ») inducamus, quae mechanismum requireret ad implendum illud cum notitia et usque ad diem reservans. .

Etsi haec bona solutio est, alia optio ad hoc problema optimize.

Praecipuum propositum est ut cache viscus [Email] = @p__linq__0 e speculatione operativa.

Munus mensae introducere [dbo].[Operative QuestionsUserMail] in datorum.

Missis Email ut parametri initus, mensam valorum recipimus:

Request No. 3


CREATE FUNCTION [dbo].[OperativeQuestionsUserMail]
(
    @Email  nvarchar(4000)
)
RETURNS
@tbl TABLE
(
    [Id]           uniqueidentifier,
    [Email]      nvarchar(4000)
)
AS
BEGIN
        INSERT INTO @tbl ([Id], [Email])
        SELECT Id, @Email
        FROM [OperativeQuestions]  AS [x] WHERE [x].[Email] = @Email;
     
    RETURN;
END

Haec refert tabula valorum cum structura notitia praedefinita.

Ut in quaestionibus operativae questionumUserMail ut optimales sint et optimae interrogationis consilia habeant, stricta structura requiritur, non Redit mensam ALIQUA RE...

Hoc in casu, inquisita Query 1 convertitur in Query 4:

Request No. 4

(@p__linq__0 nvarchar(4000))SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Join2].[Object_Id] AS [Object_Id],
[Join2].[ObjectType_Id] AS [ObjectType_Id],
[Join2].[Name] AS [Name],
[Join2].[ExternalId] AS [ExternalId]
FROM (
    SELECT Id, Email FROM [dbo].[OperativeQuestionsUserMail] (@p__linq__0)
) AS [Extent0]
INNER JOIN [dbo].[Questions] AS [Extent1] ON([Extent0].Id=[Extent1].Id)
INNER JOIN (SELECT [Extent2].[Object_Id] AS [Object_Id], [Extent2].[Question_Id] AS [Question_Id], [Extent3].[ExternalId] AS [ExternalId], [Extent3].[ObjectType_Id] AS [ObjectType_Id], [Extent4].[Name] AS [Name]
FROM [dbo].[ObjectQuestions] AS [Extent2]
INNER JOIN [dbo].[Objects] AS [Extent3] ON [Extent2].[Object_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[ObjectTypes] AS [Extent4] 
ON [Extent3].[ObjectType_Id] = [Extent4].[Id] ) AS [Join2] 
ON [Extent1].[Id] = [Join2].[Question_Id]
WHERE ([Extent1].[AnswerId] IS NULL) AND (0 = [Extent1].[Exp]);

DbContext (EF Core 2)

public class QuestionsDbContext : DbContext
{
    //...
    public DbQuery<OperativeQuestion> OperativeQuestions { get; set; }
    //...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Query<OperativeQuestion>().ToView("OperativeQuestions");
    }
}
 
public static class FromSqlQueries
{
    public static IQueryable<OperativeQuestion> GetByUserEmail(this DbQuery<OperativeQuestion> source, string Email)
        => source.FromSql($"SELECT Id, Email FROM [dbo].[OperativeQuestionsUserMail] ({Email})");
}

Final LINQ query

var businessObjectsData = await context
    .OperativeQuestions
    .GetByUserEmail(Email)
    .Include(x => x.Question)
    .Select(x => x.Question)
    .SelectMany(x => x.ObjectQuestions,
                (x, bo) => new
                {
                    Id = x.Id,
                    ObjectId = bo.Object.Id,
                    ObjectTypeId = bo.Object.ObjectType.Id,
                    ObjectTypeName = bo.Object.ObjectType.Name,
                    ObjectExternalId = bo.Object.ExternalId
                })
    .ToListAsync();

Ordo executionis temporis decidit ex 200-800 ms, ad 2-20 ms, etc., i.e., decies velocius.

Si plus mediocris accipiamus, pro 350 ms 8 ms.

Ex manifestis commodis etiam accipimus;

  1. generalis deminutio lectionis onus;
  2. significant reductionem in verisimili interclusio
  3. reducendo mediocris interclusio tempus gratum values

conclusio,

Optimization et bene-tuning of database vocat MSSQL per LINQ est quaestio quae solvi potest.

Sollicitudo et constantia magni ponderis sunt in hoc opere.

In initio processus;

  1. necesse est ut notitias, quibus petitio opera retentat (valores, selectas notitias rationes)
  2. facere proprium huius notitiae indexing
  3. recte iungendi inter mensas reprehendo

Altera ipsum iteratio manifestat:

  1. ex petitione et definit summam petitionem sparguntur
  2. repetens similis interrogationi caudices et conditiones intersectio analyzing
  3. in SSMS vel GUI for SQL Servo optimizes ipsum SQL query (medias notitias repositionis collocare, aedificans interrogatione facta inde utens hac repositione (plures esse possunt))
  4. in ultimo gradu, in fundamento inde SQL query, structura aedificatur LINQ query

Inde LINQ query sit idem in structuram ad identified meliorem SQL query ex puncto III.

agnitiones

Multi collegae gratias jobgemws ΠΈ alex_ozr de comitatu Fortis auxilium ad hanc materiam conficiendam.

Source: www.habr.com