Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server

LINQ Π½Π°Π²Π»Π΅Π·Π΅ Π² .NET ΠΊΠ°Ρ‚ΠΎ Π½ΠΎΠ² ΠΌΠΎΡ‰Π΅Π½ Π΅Π·ΠΈΠΊ Π·Π° манипулация с Π΄Π°Π½Π½ΠΈ. LINQ to SQL ΠΊΠ°Ρ‚ΠΎ част ΠΎΡ‚ Π½Π΅Π³ΠΎ позволява ΡƒΠ΄ΠΎΠ±Π½ΠΎ взаимодСйствиС с Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Entity Framework. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, чСсто ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅ Π½Π° LINQ, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈΡ‚Π΅ забравят Π΄Π° провСрят ΠΊΠ°ΠΊΠ²ΠΈ SQL заявки Ρ‰Π΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° queryable provider, Π² случая β€” Entity Framework.

НСка Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π΄Π²Π° основни ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°.
Π—Π° Ρ†Π΅Π»Ρ‚Π° Π² SQL Server Ρ‰Π΅ създадСм Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ Test ΠΈ Π² нСя Ρ‰Π΅ създадСм Π΄Π²Π΅ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° слСдния заявка:

БъздаванС Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ

USE [TEST]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Ref](
	[ID] [int] NOT NULL,
	[ID2] [int] NOT NULL,
	[Name] [nvarchar](255) NOT NULL,
	[InsertUTCDate] [datetime] NOT NULL,
 CONSTRAINT [PK_Ref] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Ref] ADD  CONSTRAINT [DF_Ref_InsertUTCDate]  DEFAULT (getutcdate()) FOR [InsertUTCDate]
GO

USE [TEST]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Customer](
	[ID] [int] NOT NULL,
	[Name] [nvarchar](255) NOT NULL,
	[Ref_ID] [int] NOT NULL,
	[InsertUTCDate] [datetime] NOT NULL,
	[Ref_ID2] [int] NOT NULL,
 CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Customer] ADD  CONSTRAINT [DF_Customer_Ref_ID]  DEFAULT ((0)) FOR [Ref_ID]
GO

ALTER TABLE [dbo].[Customer] ADD  CONSTRAINT [DF_Customer_InsertUTCDate]  DEFAULT (getutcdate()) FOR [InsertUTCDate]
GO

Π‘Π΅Π³Π° Ρ‰Π΅ запълним Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Ref с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° слСдния скрипт:

Π—Π°ΠΏΡŠΠ»Π²Π°Π½Π΅ Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Ref

USE [TEST]
GO

DECLARE @ind INT=1;

WHILE(@ind<1200000)
BEGIN
	INSERT INTO [dbo].[Ref]
           ([ID]
           ,[ID2]
           ,[Name])
    SELECT
           @ind
           ,@ind
           ,CAST(@ind AS NVARCHAR(255));

	SET @ind=@ind+1;
END 
GO

По Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π΅Π½ Π½Π°Ρ‡ΠΈΠ½ Ρ‰Π΅ запълним Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Customer с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° слСдния скрипт:

Π—Π°ΠΏΡŠΠ»Π²Π°Π½Π΅ Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Customer

USE [TEST]
GO

DECLARE @ind INT=1;
DECLARE @ind_ref INT=1;

WHILE(@ind<=12000000)
BEGIN
	IF(@ind%3=0) SET @ind_ref=1;
	ELSE IF (@ind%5=0) SET @ind_ref=2;
	ELSE IF (@ind%7=0) SET @ind_ref=3;
	ELSE IF (@ind=0) SET @ind_ref=4;
	ELSE IF (@ind=0) SET @ind_ref=5;
	ELSE IF (@ind=0) SET @ind_ref=6;
	ELSE IF (@ind=0) SET @ind_ref=7;
	ELSE IF (@ind=0) SET @ind_ref=8;
	ELSE IF (@ind=0) SET @ind_ref=9;
	ELSE IF (@ind=0) SET @ind_ref=10;
	ELSE IF (@ind=0) SET @ind_ref=11;
	ELSE SET @ind_ref=@ind90000;
	
	INSERT INTO [dbo].[Customer]
	 ([ID]
	 ,[Name]
	 ,[Ref_ID]
	 ,[Ref_ID2])
	 SELECT
	 @ind,
	 CAST(@ind AS NVARCHAR(255)),
	 @ind_ref,
	 @ind_ref;


	SET @ind=@ind+1;
END
GO

Π’Π°ΠΊΠ° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ…ΠΌΠ΅ Π΄Π²Π΅ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ, Π² Π΅Π΄Π½Π°Ρ‚Π° ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠΌΠ° Π½Π°Π΄ 1 ΠΌΠΈΠ»ΠΈΠΎΠ½ Ρ€Π΅Π΄Π° Π΄Π°Π½Π½ΠΈ, Π° Π² Π΄Ρ€ΡƒΠ³Π°Ρ‚Π° β€” Π½Π°Π΄ 10 ΠΌΠΈΠ»ΠΈΠΎΠ½Π° Ρ€Π΅Π΄Π° Π΄Π°Π½Π½ΠΈ.

Π‘Π΅Π³Π° Π² Visual Studio Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ тСстов ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Visual C# Console App (.NET Framework):

Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π° Entity Framework Π·Π° взаимодСйствиС с Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.
Π—Π° Π΄Π° Π³ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ, Ρ‰Ρ€Π°ΠΊΠ²Π°ΠΌΠ΅ с дСсния Π±ΡƒΡ‚ΠΎΠ½ Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ ΠΎΡ‚ контСкстното мСню ΠΈΠ·Π±ΠΈΡ€Π°ΠΌΠ΅ Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° NuGet ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ:

Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Π² появилото сС ΠΏΡ€ΠΎΠ·ΠΎΡ€Ρ‡Π΅ Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° NuGet ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈΡ‚Π΅ във ΠΏΠΎΠ»Π΅Ρ‚ΠΎ Π·Π° Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅ въвСТдамС Π΄ΡƒΠΌΠ°Ρ‚Π° β€žEntity Frameworkβ€œ ΠΈ ΠΈΠ·Π±ΠΈΡ€Π°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅Ρ‚Π° Entity Framework ΠΈ Π³ΠΎ инсталирамС:

Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° във Ρ„Π°ΠΉΠ»Π° App.config, слСд затварящия Ρ‚Π°Π³ configSections, трябва Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ слСдния Π±Π»ΠΎΠΊ:


Π’ connectionString трябва Π΄Π° въвСдСм стринга Π·Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅.

Π‘Π΅Π³Π° Ρ‰Π΅ създадСм Π² ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅ 3 интСрфСйса:

  1. Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ Π½Π° интСрфСйса IBaseEntityID
    namespace TestLINQ
    {
        public interface IBaseEntityID
        {
            int ID { get; set; }
        }
    }
    

  2. Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ Π½Π° интСрфСйса IBaseEntityName
    namespace TestLINQ
    {
        public interface IBaseEntityName
        {
            string Name { get; set; }
        }
    }
    

  3. Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ Π½Π° интСрфСйса IBaseNameInsertUTCDate
    namespace TestLINQ
    {
        public interface IBaseNameInsertUTCDate
        {
            DateTime InsertUTCDate { get; set; }
        }
    }
    

И Π² ΠΎΡ‚Π΄Π΅Π»Π΅Π½ Ρ„Π°ΠΉΠ» Ρ‰Π΅ създадСм основния клас BaseEntity Π·Π° Π½Π°ΡˆΠΈΡ‚Π΅ Π΄Π²Π΅ ΡΡŠΡ‰Π½ΠΎΡΡ‚ΠΈ, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ Π²ΠΊΠ»ΡŽΡ‡Π²Π° ΠΎΠ±Ρ‰ΠΈΡ‚Π΅ ΠΏΠΎΠ»Π΅Ρ‚Π°:

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ Π½Π° основния клас BaseEntity

namespace TestLINQ
{
    public class BaseEntity : IBaseEntityID, IBaseEntityName, IBaseNameInsertUTCDate
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public DateTime InsertUTCDate { get; set; }
    }
}

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Π² ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅ Ρ‰Π΅ създадСм Π½Π°ΡˆΠΈΡ‚Π΅ Π΄Π²Π΅ ΡΡŠΡ‰Π½ΠΎΡΡ‚ΠΈ:

  1. Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ Π½Π° класа Ref
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace TestLINQ
    {
        [Table("Ref")]
        public class Ref : BaseEntity
        {
            public int ID2 { get; set; }
        }
    }
    

  2. Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ Π½Π° класа Customer
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace TestLINQ
    {
        [Table("Customer")]
        public class Customer: BaseEntity
        {
            public int Ref_ID { get; set; }
            public int Ref_ID2 { get; set; }
        }
    }
    

Π‘Π΅Π³Π° Ρ‰Π΅ създадСм Π² ΠΎΡ‚Π΄Π΅Π»Π΅Π½ Ρ„Π°ΠΉΠ» контСкста UserContext:

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ Π½Π° класа UserContext

using System.Data.Entity;

namespace TestLINQ
{
    public class UserContext : DbContext
    {
        public UserContext()
            : base("DbConnection")
        {
            Database.SetInitializer(null);
        }

        public DbSet Customer { get; set; }
        public DbSet Ref { get; set; }
    }
}

ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ…ΠΌΠ΅ Π³ΠΎΡ‚ΠΎΠ²ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π·Π° ΠΏΡ€ΠΎΠ²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° тСстовС ΠΏΠΎ оптимизация с LINQ to SQL ΠΏΡ€Π΅Π· EF Π·Π° MS SQL Server:

Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server

Π‘Π΅Π³Π° Π² Ρ„Π°ΠΉΠ»Π° Program.cs Ρ‰Π΅ въвСдСм слСдния ΠΊΠΎΠ΄:

Π€Π°ΠΉΠ» Program.cs

using System;
using System.Collections.Generic;
using System.Linq;

namespace TestLINQ
{
    class Program
    {
        static void Main(string[] args)
        {
            using (UserContext db = new UserContext())
            {
                var dblog = new List();
                db.Database.Log = dblog.Add;

                var query = from e1 in db.Customer
                            from e2 in db.Ref
                            where (e1.Ref_ID == e2.ID)
                                 && (e1.Ref_ID2 == e2.ID2)
                            select new { Data1 = e1.Name, Data2 = e2.Name };

                var result = query.Take(1000).ToList();

                Console.WriteLine(dblog[1]);

                Console.ReadKey();
            }
        }
    }
}

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Ρ‰Π΅ стартирамС нашия ΠΏΡ€ΠΎΠ΅ΠΊΡ‚.

Π’ края Π½Π° ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π°Ρ‚Π° Ρ‰Π΅ сС ΠΈΠ·Π²Π΅Π΄Π΅:

Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π° SQL заявка

SELECT TOP (1000) 
    [Extent1].[Ref_ID] AS [Ref_ID], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1]
    FROM  [dbo].[Customer] AS [Extent1]
    INNER JOIN [dbo].[Ref] AS [Extent2] ON ([Extent1].[Ref_ID] = [Extent2].[ID]) AND ([Extent1].[Ref_ID2] = [Extent2].[ID2])

Π’.Π΅. Π² ΠΎΠ±Ρ‰ΠΈ Π»ΠΈΠ½ΠΈΠΈ, LINQ заявката Π΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π»Π° Π²ΠΏΠΎΠ»Π½Π΅ ΠΏΡ€ΠΈΠ΅ΠΌΠ»ΠΈΠ² SQL заявка Π·Π° MS SQL Server.

Π‘Π΅Π³Π° Ρ‰Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΠΌ условиСто И Π½Π° Π˜Π›Π˜ Π² LINQ заявката:

LINQ-Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅

var query = from e1 in db.Customer
                            from e2 in db.Ref
                            where (e1.Ref_ID == e2.ID)
                                || (e1.Ref_ID2 == e2.ID2)
                            select new { Data1 = e1.Name, Data2 = e2.Name };

И ΠΎΡ‚Π½ΠΎΠ²ΠΎ Ρ‰Π΅ стартирамС Π½Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.

Π˜Π·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Ρ‰Π΅ Π·Π°Π²ΡŠΡ€ΡˆΠΈ с Π³Ρ€Π΅ΡˆΠΊΠ°, ΡΠ²ΡŠΡ€Π·Π°Π½Π° с ΠΏΡ€Π΅Π²ΠΈΡˆΠ°Π²Π°Π½Π΅ Π½Π° Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π·Π° изпълнСниС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° ΠΎΡ‚ 30 сСкунди:

Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server

Ако Π²ΠΈΠ΄ΠΈΠΌ коя заявка Π΅ Π±ΠΈΠ»Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π° ΠΎΡ‚ LINQ:

Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server
, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° сС ΡƒΠ²Π΅Ρ€ΠΈΠΌ, Ρ‡Π΅ ΠΈΠ·Π±ΠΎΡ€Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° Ρ‡Ρ€Π΅Π· Π΄Π΅ΠΊΠ°Ρ€Ρ‚ΠΎΠ²ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π½Π° Π΄Π²Π΅ мноТСства (Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ):

Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π° SQL заявка

SELECT TOP (1000) 
    [Extent1].[Ref_ID] AS [Ref_ID], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1]
    FROM  [dbo].[Customer] AS [Extent1]
    CROSS JOIN [dbo].[Ref] AS [Extent2]
    WHERE [Extent1].[Ref_ID] = [Extent2].[ID] OR [Extent1].[Ref_ID2] = [Extent2].[ID2]

НСка ΠΏΡ€Π΅ напишСм LINQ заявката ΠΏΠΎ слСдния Π½Π°Ρ‡ΠΈΠ½:

ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Π½Π° LINQ заявка

var query = (from e1 in db.Customer
                   join e2 in db.Ref
                   on e1.Ref_ID equals e2.ID
                   select new { Data1 = e1.Name, Data2 = e2.Name }).Union(
                        from e1 in db.Customer
                        join e2 in db.Ref
                        on e1.Ref_ID2 equals e2.ID2
                        select new { Data1 = e1.Name, Data2 = e2.Name });

Π’ΠΎΠ³Π°Π²Π° Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ слСдният SQL заявка:

SQL-Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅

SELECT 
    [Limit1].[C1] AS [C1], 
    [Limit1].[C2] AS [C2], 
    [Limit1].[C3] AS [C3]
    FROM ( SELECT DISTINCT TOP (1000) 
        [UnionAll1].[C1] AS [C1], 
        [UnionAll1].[Name] AS [C2], 
        [UnionAll1].[Name1] AS [C3]
        FROM  (SELECT 
            1 AS [C1], 
            [Extent1].[Name] AS [Name], 
            [Extent2].[Name] AS [Name1]
            FROM  [dbo].[Customer] AS [Extent1]
            INNER JOIN [dbo].[Ref] AS [Extent2] ON [Extent1].[Ref_ID] = [Extent2].[ID]
        UNION ALL
            SELECT 
            1 AS [C1], 
            [Extent3].[Name] AS [Name], 
            [Extent4].[Name] AS [Name1]
            FROM  [dbo].[Customer] AS [Extent3]
            INNER JOIN [dbo].[Ref] AS [Extent4] ON [Extent3].[Ref_ID2] = [Extent4].[ID2]) AS [UnionAll1]
    )  AS [Limit1]

Π—Π° съТалСниС, Π² LINQ заявкитС условиСто Π·Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС само ΠΎΠ΄Π½ΠΎ, Π·Π°Ρ‚ΠΎΠ²Π° Π΅ възмоТно Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ Π΅ΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½Ρ‚Π½ΠΎ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ Ρ‡Ρ€Π΅Π· Π΄Π²Π° записа ΠΏΠΎ всяко условиС, послСдвани ΠΎΡ‚ ΠΎΠ±Π΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ с Union Π·Π° ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° Π΄ΡƒΠ±Π»ΠΈΠΊΠ°Ρ‚ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π΅Π΄ΠΎΠ²Π΅Ρ‚Π΅.
Π”Π°, запитванията Π² общия случай Ρ‰Π΅ сС ΠΎΠΊΠ°ΠΆΠ°Ρ‚ Π½Π΅Π΅ΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½Ρ‚Π½ΠΈ с ΠΎΠ³Π»Π΅Π΄ Π½Π° Ρ„Π°ΠΊΡ‚Π°, Ρ‡Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Π²ΡŠΡ€Π½Π°Ρ‚ΠΈ пълни Π΄ΡƒΠ±Π»ΠΈΠΊΠ°Ρ‚ΠΈ Π½Π° Ρ€Π΅Π΄ΠΎΠ²Π΅Ρ‚Π΅. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, Π² рСалния ΠΆΠΈΠ²ΠΎΡ‚ ΠΏΡŠΠ»Π½ΠΈΡ‚Π΅ Π΄ΡƒΠ±Π»ΠΈΡ€Π°Ρ‰ΠΈ Ρ€Π΅Π΄ΠΎΠ²Π΅ Π½Π΅ са Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ ΠΈ сС ΠΎΠΏΠΈΡ‚Π²Π°Ρ‚ Π΄Π° сС ΠΎΡ‚ΡŠΡ€Π²Π°Ρ‚ ΠΎΡ‚ тях.

Π‘Π΅Π³Π° Π΄Π° сравним ΠΏΠ»Π°Π½ΠΎΠ²Π΅Ρ‚Π΅ Π·Π° изпълнСниС Π½Π° Ρ‚Π΅Π·ΠΈ Π΄Π²Π΅ запитвания:

  1. Π·Π° CROSS JOIN срСдното Π²Ρ€Π΅ΠΌΠ΅ Π·Π° изпълнСниС Π΅ 195 сСкунди:
    Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server
  2. Π·Π° INNER JOIN-UNION срСдното Π²Ρ€Π΅ΠΌΠ΅ Π·Π° изпълнСниС Π΅ ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ ΠΎΡ‚ 24 сСкунди:
    Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server

ΠšΠ°ΠΊΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π²ΠΈΠ΄ΠΈΠΌ ΠΎΡ‚ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈΡ‚Π΅, Π·Π° Π΄Π²Π΅ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ с ΠΌΠΈΠ»ΠΈΠΎΠ½ΠΈ записи ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Π½ΠΎΡ‚ΠΎ LINQ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ Ρ€Π°Π±ΠΎΡ‚ΠΈ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΏΠΎ-Π±ΡŠΡ€Π·ΠΎ ΠΎΡ‚ Π½Π΅ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Π½ΠΎΡ‚ΠΎ.

Π—Π° Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° с И Π² условията Π½Π° LINQ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ ΠΎΡ‚ Π²ΠΈΠ΄Π°:

LINQ-Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅

var query = from e1 in db.Customer
                            from e2 in db.Ref
                            where (e1.Ref_ID == e2.ID)
                                 && (e1.Ref_ID2 == e2.ID2)
                            select new { Data1 = e1.Name, Data2 = e2.Name };

ΠΏΠΎΡ‡Ρ‚ΠΈ Π²ΠΈΠ½Π°Π³ΠΈ Ρ‰Π΅ бъдС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½ ΠΏΡ€Π°Π²ΠΈΠ»Π΅Π½ SQL Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅, ΠΊΠΎΠ΅Ρ‚ΠΎ Ρ‰Π΅ сС изпълнява срСдно ΠΎΠΊΠΎΠ»ΠΎ 1 сСкунда:

Някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания Π² C#.NET Π·Π° MS SQL Server
Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ°, Π·Π° ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ†ΠΈΠΈ LINQ to Objects вмСсто Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ ΠΎΡ‚ Π²ΠΈΠ΄Π°:

LINQ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ (1-Π²ΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚)

var query = from e1 in seq1
                            from e2 in seq2
                            where (e1.Key1==e2.Key1)
                               && (e1.Key2==e2.Key2)
                            select new { Data1 = e1.Data, Data2 = e2.Data };

ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ ΠΎΡ‚ Π²ΠΈΠ΄Π°:

LINQ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ (2-Ρ€ΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚)

var query = from e1 in seq1
                            join e2 in seq2
                            on new { e1.Key1, e1.Key2 } equals new { e2.Key1, e2.Key2 }
                            select new { Data1 = e1.Data, Data2 = e2.Data };

ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ:

ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ½Π΅ Π½Π° Π΄Π²Π° масива

Para[] seq1 = new[] { new Para { Key1 = 1, Key2 = 2, Data = "777" }, new Para { Key1 = 2, Key2 = 3, Data = "888" }, new Para { Key1 = 3, Key2 = 4, Data = "999" } };
Para[] seq2 = new[] { new Para { Key1 = 1, Key2 = 2, Data = "777" }, new Para { Key1 = 2, Key2 = 3, Data = "888" }, new Para { Key1 = 3, Key2 = 5, Data = "999" } };

, Π° Ρ‚ΠΈΠΏΡŠΡ‚ Para сС опрСдСля ΠΏΠΎ слСдния Π½Π°Ρ‡ΠΈΠ½:

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π½Π° Ρ‚ΠΈΠΏΠ° Para

class Para
{
        public int Key1, Key2;
        public string Data;
}

Π’Π°ΠΊΠ°, Π½ΠΈΠ΅ Ρ€Π°Π·Π³Π»Π΅Π΄Π°Ρ…ΠΌΠ΅ някои аспСкти Π½Π° оптимизацията Π½Π° LINQ запитвания към MS SQL Server.

Π—Π° съТалСниС, Π΄ΠΎΡ€ΠΈ ΠΎΠΏΠΈΡ‚Π½ΠΈΡ‚Π΅ ΠΈ Π²ΠΎΠ΄Π΅Ρ‰ΠΈ .NET Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈ забравят, Ρ‡Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° Ρ€Π°Π·Π±ΠΈΡ€Π°Ρ‚ ΠΊΠ°ΠΊΠ²ΠΎ правят Π·Π°Π΄ кулиситС Ρ‚Π΅Π·ΠΈ инструкции, ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π΅Π½ случай Ρ‚Π΅ стават ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‰ΠΈ ΠΈ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π·Π°ΠΊΠ»Π°Π΄Π°Ρ‚ Π±ΠΎΠΌΠ±Π° със Π·Π°Π±Π°Π²Π΅Π½ΠΎ дСйствиС Π² Π±ΡŠΠ΄Π΅Ρ‰Π΅, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΏΡ€ΠΈ ΠΌΠ°Ρ‰Π°Π±ΠΈΡ€Π°Π½Π΅ Π½Π° софтуСрното Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, Ρ‚Π°ΠΊΠ° ΠΈ ΠΏΡ€ΠΈ Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΈ измСнСния Π½Π° Π²ΡŠΠ½ΡˆΠ½ΠΈΡ‚Π΅ условия Π½Π° срСдата.

Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° бСшС Π½Π°ΠΏΡ€Π°Π²Π΅Π½ малък ΠΏΡ€Π΅Π³Π»Π΅Π΄ ΠΈ Ρ‚ΡƒΠΊ..

Π˜Π·Ρ…ΠΎΠ΄Π½ΠΈΡ‚Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅ Π·Π° тСста - самият ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, ΡΡŠΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ TEST, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ ΠΏΠΎΠΏΡŠΠ»Π²Π°Π½Π΅Ρ‚ΠΎ с Π΄Π°Π½Π½ΠΈ Π½Π° Ρ‚Π΅Π·ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ сС Π½Π°ΠΌΠΈΡ€Π° Ρ‚ΡƒΠΊ..
Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° Π² Ρ‚ΠΎΠ·ΠΈ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ Π² ΠΏΠ°ΠΏΠΊΠ°Ρ‚Π° Plans сС Π½Π°ΠΌΠΈΡ€Π°Ρ‚ ΠΏΠ»Π°Π½ΠΎΠ²Π΅Ρ‚Π΅ Π·Π° изпълнСниС Π½Π° заявки с условия Π˜Π›Π˜.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster