मैंने अपनी प्रदर्शन समस्या पर बहुत कुछ खोजा और विभिन्न प्रकार की सभी कोशिशों की कोशिश की, लेकिन मुझे लगता है कि यह पर्याप्त तेज़ी से काम करने के लिए प्रतीत नहीं होता है। यहां मेरी सबसे सरल रूप में मेरी समस्या है:कोडफर्स्ट लोडिंग 1 पेरेंट 25 000 बच्चों से जुड़ा हुआ है धीमा
मैं इकाई फ्रेमवर्क 5 का उपयोग कर रहा हूं और जब मैं उस अभिभावक का चयन करता हूं तो मैं अभिभावक के बच्चे के उदाहरणों को आलसी लोड करने में सक्षम होना चाहता हूं, इसलिए मुझे पूरे को खींचने की ज़रूरत नहीं है डेटाबेस। हालांकि मुझे बच्चों को आलसी लोडिंग के साथ प्रदर्शन समस्याएं आ रही हैं। मुझे लगता है कि समस्या माता-पिता और बच्चों के बीच नेविगेशन गुणों का तार है। मैं यह भी सोच रहा हूं कि यह कुछ गलत होना चाहिए क्योंकि मुझे विश्वास है कि यह एक साधारण मामला है।
तो मैंने समस्या को अलग करने के लिए एक आलसी लोड का परीक्षण करने के लिए एक कार्यक्रम प्रस्तुत किया।
यहाँ टेस्ट है:
मैं एक POCO जनक वर्ग और एक बाल POCO वर्ग बनाया। माता-पिता में बच्चे हैं और बच्चे के पास 1 माता-पिता हैं। एसक्यूएल सर्वर डेटाबेस में केवल 1 अभिभावक और उस एकल माता-पिता के लिए 25 000 बच्चे हैं। मैंने इस डेटा को लोड करने के लिए विभिन्न तरीकों का प्रयास किया। जब भी मैं एक ही डीबीकॉन्टेक्स्ट में बच्चों और माता-पिता को लोड करता हूं, तो इसमें काफी समय लगता है। लेकिन अगर मैं उन्हें विभिन्न डीबी कॉन्टैक्स में लोड करता हूं, तो यह वास्तव में तेज़ हो जाता है। हालांकि, मैं उन उदाहरणों को एक ही डीबीकॉन्टेक्स्ट में रखना चाहता हूं।
यहाँ अपने परीक्षण सेटअप और सब कुछ है कि आप इसे दोहराने की जरूरत है:
Pocos:
public class Parent
{
public int ParentId { get; set; }
public string Name { get; set; }
public virtual List<Child> Childs { get; set; }
}
public class Child
{
public int ChildId { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
public virtual Parent Parent { get; set; }
}
DbContext:
public class Entities : DbContext
{
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Childs { get; set; }
}
TSQL स्क्रिप्ट बनाने के लिए डाटाबेस ase और डेटा:
USE [master]
GO
IF EXISTS(SELECT name FROM sys.databases
WHERE name = 'PerformanceParentChild')
alter database [PerformanceParentChild] set single_user with rollback immediate
DROP DATABASE [PerformanceParentChild]
GO
CREATE DATABASE [PerformanceParentChild]
GO
USE [PerformanceParentChild]
GO
BEGIN TRAN T1;
SET NOCOUNT ON
CREATE TABLE [dbo].[Parents]
(
[ParentId] [int] CONSTRAINT PK_Parents PRIMARY KEY,
[Name] [nvarchar](200) NULL
)
GO
CREATE TABLE [dbo].[Children]
(
[ChildId] [int] CONSTRAINT PK_Children PRIMARY KEY,
[ParentId] [int] NOT NULL,
[Name] [nvarchar](200) NULL
)
GO
INSERT INTO Parents (ParentId, Name)
VALUES (1, 'Parent')
DECLARE @nbChildren int;
DECLARE @childId int;
SET @nbChildren = 25000;
SET @childId = 0;
WHILE @childId < @nbChildren
BEGIN
SET @childId = @childId + 1;
INSERT INTO [dbo].[Children] (ChildId, ParentId, Name)
VALUES (@childId, 1, 'Child #' + convert(nvarchar(5), @childId))
END
CREATE NONCLUSTERED INDEX [IX_ParentId] ON [dbo].[Children]
(
[ParentId] ASC
)
GO
ALTER TABLE [dbo].[Children] ADD CONSTRAINT [FK_Children.Parents_ParentId] FOREIGN KEY([ParentId])
REFERENCES [dbo].[Parents] ([ParentId])
GO
COMMIT TRAN T1;
अनुप्रयोग।config कनेक्शन स्ट्रिंग युक्त
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add
name="Entities"
providerName="System.Data.SqlClient"
connectionString="Server=localhost;Database=PerformanceParentChild;Trusted_Connection=true;"/>
</connectionStrings>
</configuration>
टेस्ट कंसोल वर्ग:
लोड केवल DbSet से माता-पिता:
class Program
{
static void Main(string[] args)
{
List<Parent> parents;
List<Child> children;
Entities entities;
DateTime before;
TimeSpan childrenLoadElapsed;
TimeSpan parentLoadElapsed;
using (entities = new Entities())
{
before = DateTime.Now;
parents = entities.Parents.ToList();
parentLoadElapsed = DateTime.Now - before;
System.Diagnostics.Debug.WriteLine("Load only the parent from DbSet:" + parentLoadElapsed.TotalSeconds + " seconds");
}
using (entities = new Entities())
{
before = DateTime.Now;
children = entities.Childs.ToList();
childrenLoadElapsed = DateTime.Now - before;
System.Diagnostics.Debug.WriteLine("Load only the children from DbSet:" + childrenLoadElapsed.TotalSeconds + " seconds");
}
using (entities = new Entities())
{
before = DateTime.Now;
parents = entities.Parents.ToList();
parentLoadElapsed = DateTime.Now - before;
before = DateTime.Now;
children = entities.Childs.ToList();
childrenLoadElapsed = DateTime.Now - before;
System.Diagnostics.Debug.WriteLine("Load the parent from DbSet:" + parentLoadElapsed.TotalSeconds + " seconds" +
", then load the children from DbSet:" + childrenLoadElapsed.TotalSeconds + " seconds");
}
using (entities = new Entities())
{
before = DateTime.Now;
children = entities.Childs.ToList();
childrenLoadElapsed = DateTime.Now - before;
before = DateTime.Now;
parents = entities.Parents.ToList();
parentLoadElapsed = DateTime.Now - before;
System.Diagnostics.Debug.WriteLine("Load the children from DbSet:" + childrenLoadElapsed.TotalSeconds + " seconds" +
", then load the parent from DbSet:" + parentLoadElapsed.TotalSeconds + " seconds");
}
using (entities = new Entities())
{
before = DateTime.Now;
parents = entities.Parents.ToList();
parentLoadElapsed = DateTime.Now - before;
before = DateTime.Now;
children = parents[0].Childs;
childrenLoadElapsed = DateTime.Now - before;
System.Diagnostics.Debug.WriteLine("Load the parent from DbSet:" + parentLoadElapsed.TotalSeconds + " seconds" +
", then load the children from Parent's lazy loaded navigation property:" + childrenLoadElapsed.TotalSeconds + " seconds");
}
using (entities = new Entities())
{
before = DateTime.Now;
parents = entities.Parents.Include(p => p.Childs).ToList();
parentLoadElapsed = DateTime.Now - before;
System.Diagnostics.Debug.WriteLine("Load the parent from DbSet and children from include:" + parentLoadElapsed.TotalSeconds + " seconds");
}
using (entities = new Entities())
{
entities.Configuration.ProxyCreationEnabled = false;
entities.Configuration.AutoDetectChangesEnabled = false;
entities.Configuration.LazyLoadingEnabled = false;
entities.Configuration.ValidateOnSaveEnabled = false;
before = DateTime.Now;
parents = entities.Parents.Include(p => p.Childs).ToList();
parentLoadElapsed = DateTime.Now - before;
System.Diagnostics.Debug.WriteLine("Load the parent from DbSet and children from include:" + parentLoadElapsed.TotalSeconds + " seconds with everything turned off");
}
}
}
यहाँ उन परीक्षण के परिणाम हैं 0,972 सेकंड
केवल डीबीसेट से बच्चों को लोड करें: 0,714 सेकंड onds
लोड DbSet से माता-पिता: 8,6026 सेकंड
लोड DbSet से बच्चों: 0,6864 सेकंड, तो DbSet से माता-पिता को लोड: 7,5816159 0,001 सेकंड है, तो DbSet से बच्चों को लोड सेकंड
लोड DbSet से माता-पिता: 0 सेकंड, तो अभिभावक की आलसी लोड नेविगेशन संपत्ति से बच्चों को लोड: 8,5644549 सेकंड
लोड DbSet और से बच्चों से माता-पिता शामिल हैं: 8,6428788 सेकंड
लोआ घ DbSet और से बच्चों से माता-पिता शामिल हैं: सब कुछ के साथ 9,1416586 सेकंड बंद
दिया विश्लेषण
जब भी माता-पिता और बच्चों के एक ही DbContext में हैं, यह एक लंबा समय लगता (9 सेकंड) सब कुछ तार करने के लिए। मैंने प्रॉक्सी सृजन से लेकर आलसी लोडिंग तक सबकुछ बंद करने का भी प्रयास किया, लेकिन इसका कोई फायदा नहीं हुआ। क्या कोई मेरी सहायता कर सकता है ?
+1: महान प्रश्न और विश्लेषण! – Slauma