C#.NET дээр LINQ асуулгыг оновчтой болгох аргууд

Танилцуулга

В энэ нийтлэл зарим оновчлолын аргуудыг авч үзсэн LINQ асуулга.
Энд бид мөн холбоотой кодыг оновчтой болгох хэд хэдэн аргыг танилцуулж байна LINQ асуулга.

Энэ нь мэдэгдэж байна LINQ(Language-Integrated Query) нь өгөгдлийн эх сурвалжийг асуухад хялбар бөгөөд тохиромжтой хэл юм.

А LINQ to SQL нь DBMS дахь өгөгдөлд хандах технологи юм. Энэ нь өгөгдөлтэй ажиллах хүчирхэг хэрэгсэл бөгөөд асуулга нь мэдүүлгийн хэлээр бүтээгдэж, дараа нь хөрвүүлэх болно. SQL асуулга платформ болон өгөгдлийн сангийн серверт гүйцэтгэхээр илгээсэн. Манай тохиолдолд DBMS гэж бид хэлж байна MS SQL сервер.

Гэсэн хэдий ч, LINQ асуулга оновчтой бичигдсэн болгон хувиргадаггүй SQL асуулга, туршлагатай DBA оновчлолын бүхий л нарийн ширийн зүйлийг бичиж чаддаг SQL асуулга:

  1. оновчтой холболтууд (НЭГДЭХ) болон үр дүнг шүүх (WHERE)
  2. холболт, бүлгийн нөхцөлийг ашиглах олон нюансууд
  3. нөхцлүүдийг орлуулах олон өөрчлөлт IN тухай БАЙНАи БАЙХГҮЙ БАЙНА, <> асаалттай БАЙНА
  4. түр зуурын хүснэгт, CTE, хүснэгтийн хувьсагчаар дамжуулан үр дүнгийн завсрын кэш хийх
  5. өгүүлбэр ашиглах (OPTION) заавар болон хүснэгтийн зөвлөмжийн хамт Хамт (...)
  6. Сонголт хийх явцад илүүдэл өгөгдлийн уншилтаас ангижрах нэг хэрэгсэл болгон индексжүүлсэн харагдацыг ашиглах

Үр дүнд нь гүйцэтгэлийн гол бэрхшээлүүд SQL асуулга эмхэтгэх үед LINQ асуулга Тэдгээр нь:

  1. нэг хүсэлтэд өгөгдөл сонгох механизмыг бүхэлд нь нэгтгэх
  2. Кодын ижил блокуудыг олшруулж, улмаар олон тооны шаардлагагүй өгөгдлийг уншихад хүргэдэг.
  3. олон бүрэлдэхүүн хэсэгтэй нөхцлийн бүлгүүд (логик "ба" ба "эсвэл") - БОЛОН и OR, нарийн төвөгтэй нөхцөл байдалд нэгтгэх нь шаардлагатай талбаруудад тохирох кластер бус индексүүдтэй оновчтой тохируулагч нь эцэст нь кластерийн индексийг сканнердаж эхэлдэг (ИНДЕКС SCAN) нөхцлийн бүлгээр
  4. Дэд асуулгад гүнзгий үүрлэх нь задлан шинжлэхэд маш их асуудал үүсгэдэг SQL мэдэгдлүүд болон хөгжүүлэгчид талаас асуулга төлөвлөгөөний дүн шинжилгээ болон DBA

Оновчлолын арга

Одоо шууд оновчлолын аргууд руу шилжье.

1) Нэмэлт индексжүүлэлт

Гол сонголтын хүснэгтүүд дээрх шүүлтүүрүүдийг авч үзэх нь хамгийн сайн арга юм, учир нь ихэвчлэн бүх асуулга нь нэг эсвэл хоёр үндсэн хүснэгт (програмууд-хүмүүс-үйл ажиллагаа) болон стандарт багц нөхцлөөр (Хаалттай, Цуцлагдсан, Идэвхжүүлсэн, Төлөв) баригдсан байдаг. Тодорхойлсон дээжинд тохирох индексийг бий болгох нь чухал юм.

Энэ шийдэл нь эдгээр талбаруудыг сонгоход утга учиртай бөгөөд буцаасан багцыг асуулгад ихээхэн хязгаарладаг.

Тухайлбал, манайд 500000 мянган өргөдөл байна. Гэсэн хэдий ч, зөвхөн 2000 идэвхтэй програмууд байдаг. Дараа нь зөв сонгосон индекс биднийг аврах болно ИНДЕКС SCAN том ширээн дээр байрлуулж, кластер бус индексээр дамжуулан өгөгдлийг хурдан сонгох боломжийг танд олгоно.

Мөн асуулгын төлөвлөгөөг задлан шинжлэх эсвэл системийн харагдацын статистикийг цуглуулах замаар индексийн дутагдлыг тодорхойлж болно. MS SQL сервер:

  1. sys.dm_db_дутуу_index_groups
  2. sys.dm_db_index_group_stats дутагдаж байна
  3. sys.dm_db_index_details дутуу байна

Бүх харах өгөгдөл нь орон зайн индексээс бусад дутуу индексүүдийн талаарх мэдээллийг агуулна.

Гэсэн хэдий ч индекс ба кэш нь ихэвчлэн муу бичсэн үр дагавартай тэмцэх арга юм LINQ асуулга и SQL асуулга.

Амьдралын хатуу ширүүн туршлагаас харахад бизнесийн онцлог шинж чанаруудыг тодорхой хугацаанд хэрэгжүүлэх нь ихэвчлэн чухал байдаг. Тиймээс, хүнд хүсэлтийг кэшийн тусламжтайгаар ихэвчлэн арын дэвсгэр рүү шилжүүлдэг.

Энэ нь зарим талаар үндэслэлтэй, учир нь хэрэглэгч хамгийн сүүлийн үеийн өгөгдөлд үргэлж хэрэгтэй байдаггүй бөгөөд хэрэглэгчийн интерфэйсийн хүлээн зөвшөөрөгдөх түвшний хариу үйлдэл байдаг.

Энэ арга нь бизнесийн хэрэгцээг шийдвэрлэх боломжийг олгодог боловч асуудлын шийдлийг хойшлуулснаар мэдээллийн системийн гүйцэтгэлийг бууруулдаг.

Шаардлагатай индексүүдийг хайж олох явцад санал болгож байгааг санах нь зүйтэй MS SQL Оновчлол нь дараах нөхцөлд буруу байж болно.

  1. хэрэв ижил төстэй талбар бүхий индексүүд аль хэдийн байгаа бол
  2. Хэрэв индексжүүлэлтийн хязгаарлалтын улмаас хүснэгтийн талбаруудыг индексжүүлэх боломжгүй бол (илүү дэлгэрэнгүй тайлбарласан болно) энд).

2) Шинж чанаруудыг нэг шинэ шинж чанарт нэгтгэх

Заримдаа бүлэг нөхцлийн үндэс болох нэг хүснэгтийн зарим талбарыг нэг шинэ талбар оруулах замаар сольж болно.

Энэ нь ихэвчлэн бит эсвэл бүхэл тоотой статусын талбаруудын хувьд үнэн юм.

Жишээ нь:

Хаалттай = 0 БА Цуцлагдсан = 0 БА идэвхжүүлсэн = 0 -ээр солигдоно Статус = 1.

Хүснэгтэд эдгээр статусыг оруулахын тулд бүхэл тоон статусын шинж чанарыг энд оруулав. Дараа нь энэ шинэ шинж чанарыг индексжүүлнэ.

Энэ нь гүйцэтгэлийн асуудлыг шийдвэрлэх үндсэн шийдэл юм, учир нь бид шаардлагагүй тооцоололгүйгээр өгөгдөлд ханддаг.

3) Үзэл бодлоо бодит болгох

Харамсалтай нь, онд LINQ асуулга Түр зуурын хүснэгт, CTE болон хүснэгтийн хувьсагчдыг шууд ашиглах боломжгүй.

Гэсэн хэдий ч, энэ тохиолдолд оновчтой болгох өөр нэг арга бий - индексжүүлсэн үзэл бодол.

Нөхцөл байдлын бүлэг (дээрх жишээнээс) Хаалттай = 0 БА Цуцлагдсан = 0 БА идэвхжүүлсэн = 0 (эсвэл бусад ижил төстэй нөхцлүүдийн багц) нь тэдгээрийг том багцаас жижиг зүсмэл өгөгдлийг кэш болгон индексжүүлсэн хэлбэрээр ашиглахад тохиромжтой сонголт болдог.

Гэхдээ үзэл бодлыг хэрэгжүүлэхэд хэд хэдэн хязгаарлалт байдаг:

  1. дэд асуулга, заалт ашиглах БАЙНА ашиглан солих хэрэгтэй НЭГДЭХ
  2. Та өгүүлбэр ашиглаж чадахгүй UNION, БҮХ ЮМ, ТӨЛӨВЛӨГӨӨ, ОРШИЛ
  3. Та хүснэгтийн зөвлөмж, заалтыг ашиглах боломжгүй OPTION
  4. циклтэй ажиллах боломж байхгүй
  5. Өөр өөр хүснэгтээс өгөгдлийг нэг харагдацаар харуулах боломжгүй

Индексжүүлсэн харагдацын бодит ашиг тусыг зөвхөн индексжүүлснээр л олж авах боломжтой гэдгийг санах нь чухал юм.

Гэхдээ харахыг дуудахдаа эдгээр индексийг ашиглахгүй байж болох бөгөөд тэдгээрийг тодорхой ашиглахын тулд та зааж өгөх ёстой. WITH(NO EXPAND).

Оноос хойш LINQ асуулга Хүснэгтийн зөвлөмжийг тодорхойлох боломжгүй тул та өөр дүрслэл үүсгэх хэрэгтэй - дараах хэлбэрийн "боодол":

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

4) Хүснэгтийн функцуудыг ашиглах

Ихэнхдээ ордог LINQ асуулга Нарийн төвөгтэй бүтэцтэй харагдацыг ашигласан дэд асуулгын том блокууд эсвэл блокууд нь маш нарийн төвөгтэй, оновчтой бус гүйцэтгэлийн бүтэцтэй эцсийн асуулга үүсгэдэг.

Хүснэгтийн функцуудыг ашиглахын гол давуу талууд LINQ асуулга:

  1. Үзсэн тохиолдлын нэгэн адил объект болгон ашиглах, зааж өгөх чадвар, гэхдээ та оролтын параметрүүдийн багцыг дамжуулж болно:
    FROM FUNCTION(@param1, @param2 ...)
    Үүний үр дүнд уян хатан өгөгдлийн түүвэрлэлтэд хүрч болно
  2. Хүснэгтийн функцийг ашиглах тохиолдолд дээр дурдсан индексжүүлсэн харагдацтай адил хатуу хязгаарлалт байхгүй.
    1. Хүснэгтийн зөвлөмжүүд:
      дамжуулан LINQ Та асуулга хийхдээ аль индексийг ашиглахыг зааж өгөх боломжгүй бөгөөд өгөгдөл тусгаарлах түвшинг тодорхойлох боломжгүй.
      Гэхдээ функц нь эдгээр чадвартай байдаг.
      Функцийн тусламжтайгаар та индексүүдтэй ажиллах дүрэм, өгөгдөл тусгаарлах түвшинг тодорхойлсон нэлээд тогтмол асуулгын төлөвлөгөөнд хүрч чадна.
    2. Функцийг ашиглах нь индексжүүлсэн харагдацтай харьцуулахад дараахь зүйлийг авах боломжийг олгоно.
      • өгөгдлийн түүвэрлэлтийн нарийн төвөгтэй логик (гогцоо ашиглаж байсан ч гэсэн)
      • олон янзын хүснэгтээс өгөгдөл татаж авах
      • ашиглах UNION и БАЙНА

  3. Санал болгох OPTION Бид зэрэгцээ хяналтыг хангах шаардлагатай үед маш хэрэгтэй СОНГОЛТ(MAXDOP N), асуулгын гүйцэтгэлийн төлөвлөгөөний дараалал. Жишээлбэл:
    • та асуулгын төлөвлөгөөг албадан дахин бүтээхийг зааж өгч болно СОНГОЛТ (дахин эмхэтгэх)
    • асуулгад заасан нэгдэх дарааллыг ашиглахын тулд асуулгын төлөвлөгөөг албадах эсэхийг та тодорхойлж болно СОНГОЛТ (Албадан ЗАХИАЛГА)

    талаар дэлгэрэнгүй мэдээлэл OPTION тодорхойлсон энд.

  4. Хамгийн нарийн бөгөөд хамгийн шаардлагатай өгөгдлийн зүсмэлийг ашиглах:
    Том өгөгдлийн багцыг кэшэд хадгалах шаардлагагүй (индексжүүлсэн харагдацтай адил), үүнээс та өгөгдлийг параметрээр шүүх шаардлагатай хэвээр байна.
    Жишээлбэл, шүүлтүүр нь хүснэгт байдаг WHERE гурван талбарыг ашигладаг (а, б, в).

    Уламжлал ёсоор бол бүх хүсэлт тогтмол нөхцөлтэй байдаг a = 0 ба b = 0.

    Гэсэн хэдий ч талбайн хүсэлтийг c илүү хувьсагч.

    Нөхцөл байцгаая a = 0 ба b = 0 Энэ нь бидэнд шаардлагатай үр дүнгийн багцыг мянга мянган бичлэгээр хязгаарлахад үнэхээр тусалдаг, гэхдээ нөхцөл байдал хэвээр байна с сонголтыг зуун бичлэг хүртэл нарийсгана.

    Энд хүснэгтийн функц нь илүү сайн сонголт байж магадгүй юм.

    Түүнчлэн, хүснэгтийн функц нь гүйцэтгэлийн хугацаанд илүү урьдчилан таамаглах боломжтой бөгөөд тогтвортой байдаг.

жишээ

Асуултуудын мэдээллийн санг ашиглан жишээ хэрэгжүүлэлтийн жишээг авч үзье.

Хүсэлт байна SELECT, хэд хэдэн хүснэгтийг нэгтгэж, нэг харагдац ашигладаг (OperativeQuestions), харьяаллыг имэйлээр шалгадаг (дээр БАЙНА) "Шуурхай асуултууд" руу:

Хүсэлт No1

(@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])
));

Харагдах байдал нь нэлээд төвөгтэй бүтэцтэй: энэ нь дэд асуулгад нэгдсэн бөгөөд эрэмбэлэх аргыг ашигладаг ДҮРЭМ, энэ нь ерөнхийдөө нэлээд их нөөц шаардсан үйл ажиллагаа юм.

OperativeQuestions-ийн жишээ нь арван мянга орчим бичлэг юм.

Энэ асуулгын гол асуудал нь гадаад асуулгын бүртгэлүүдийн хувьд дотоод дэд асуулга [OperativeQuestions] харагдац дээр хийгдэж байгаа бөгөөд энэ нь [И-мэйл] = @p__linq__0-д гаралтын сонголтыг хязгаарлах боломжийг бидэнд олгоно. БАЙНА) хэдэн зуун бичлэг хүртэл.

Дэд асуулга нь [И-мэйл] = @p__linq__0 гэж нэг удаа бүртгэлийг тооцоолох ёстой юм шиг санагдаж магадгүй бөгөөд дараа нь эдгээр хэдэн зуун бичлэгийг асуулттай Id-ээр холбох ёстой бөгөөд асуулга хурдан байх болно.

Үнэн хэрэгтээ бүх хүснэгтүүдийн дараалсан холболт байдаг: Id асуултуудын OperativeQuestions-ийн Id-тэй харьцах эсэхийг шалгах, имэйлээр шүүх.

Үнэн хэрэгтээ, хүсэлт нь бүх арван мянган OperativeQuestions бүртгэлтэй ажилладаг боловч зөвхөн сонирхсон мэдээлэл нь имэйлээр хэрэгтэй болно.

OperativeQuestions харах текст:

Хүсэлт No2

 
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");
    }
}

Анхны LINQ асуулга

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();

Энэ тохиолдолд бид дэд бүтцийн өөрчлөлтгүйгээр, бэлэн үр дүн бүхий тусдаа хүснэгтийг ("Идэвхтэй асуулга") оруулахгүйгээр энэ асуудлыг шийдвэрлэх арга замыг авч үзэж байгаа бөгөөд үүнийг мэдээллээр дүүргэх, шинэчилж байх механизм шаардлагатай болно. .

Хэдийгээр энэ нь сайн шийдэл боловч энэ асуудлыг оновчтой болгох өөр нэг хувилбар бий.

Гол зорилго нь OperativeQuestions харагдацаас [И-мэйл] = @p__linq__0-ийн оруулгуудыг кэшлэх явдал юм.

[dbo].[OperativeQuestionsUserMail] хүснэгтийн функцийг мэдээллийн санд оруулна.

Имэйлийг оролтын параметр болгон илгээснээр бид утгуудын хүснэгтийг буцааж авна.

Хүсэлт No3


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

Энэ нь урьдчилан тодорхойлсон өгөгдлийн бүтэцтэй утгуудын хүснэгтийг буцаана.

OperativeQuestionsUserMail-ийн асуулга оновчтой, оновчтой асуулгын төлөвлөгөөтэй байхын тулд хатуу бүтэц шаардагдана. Хүснэгтийг БУЦАХ ГЭДЭГ...

Энэ тохиолдолд шаардлагатай Query 1-ийг Query 4 болгон хувиргана:

Хүсэлт No4

(@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})");
}

Эцсийн LINQ асуулга

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();

Гүйцэтгэх хугацаа 200-800 мс-ээс 2-20 мс хүртэл буурч, өөрөөр хэлбэл хэдэн арван дахин хурдан болсон.

Хэрэв бид үүнийг дунджаар авч үзвэл 350 мс биш харин 8 мс байна.

Илэрхий давуу талуудаас бид дараахь зүйлийг олж авдаг.

  1. унших ачааллын ерөнхий бууралт,
  2. блоклох магадлал мэдэгдэхүйц буурдаг
  3. блоклох дундаж хугацааг зөвшөөрөгдөх хэмжээнд хүртэл бууруулах

дүгнэлт

Өгөгдлийн сангийн дуудлагыг оновчтой болгох, нарийн тохируулах MS SQL дамжуулан LINQ шийдвэрлэх боломжтой асуудал юм.

Энэ ажилд анхааралтай, тууштай байх нь маш чухал юм.

Процессын эхэнд:

  1. хүсэлт ажиллаж байгаа өгөгдлийг шалгах шаардлагатай (утга, сонгосон өгөгдлийн төрөл)
  2. энэ өгөгдлийг зөв индексжүүлэх
  3. Хүснэгтүүдийн хооронд холболтын нөхцлийн зөв эсэхийг шалгах

Дараагийн оновчлолын давталт нь:

  1. хүсэлтийн үндэс бөгөөд үндсэн хүсэлтийн шүүлтүүрийг тодорхойлно
  2. ижил төстэй асуулгын блокуудыг давтаж, нөхцлийн огтлолцолд дүн шинжилгээ хийх
  3. SSMS эсвэл бусад GUI дээр SQL сервер өөрийгөө оновчтой болгодог SQL асуулга (завсрын өгөгдлийн санг хуваарилах, энэ санг ашиглан үүссэн асуулга үүсгэх (хэд хэдэн байж болно))
  4. эцсийн шатанд үр дүнг үндэс болгон авна SQL асуулга, бүтцийг дахин барьж байна LINQ асуулга

Үүний үр дүнд LINQ асуулга тодорхойлсон оновчтой бүтэцтэй ижил байх ёстой SQL асуулга 3-р цэгээс.

Талархал

Хамт олондоо маш их баярлалаа jobgemws и alex_ozr компаниас Фортис Энэ материалыг бэлтгэхэд туслах.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх