Performance issue in IEnumerable type when querying large amount of data with LINQ
up vote
0
down vote
favorite
I'm using LINQ to execute a query on a List type variable with a large amount of data (over a million). For performance purposes I'm using IEnumerable to store the results but when I try to access it there is a slight delay.
Specifically I want to see if the query produced any results, but when I use the .Count() or .Any() functions the performance drops.
I read that for IEnumerable types the execution of the query happens at the time of need, hence the delay. Is there a way to see if the IEnumerable has elements inside it without having that much delay?
This is what I'm trying to run.
IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.CompareNameObjects(n))));
and here are my classes
public class Entity
{
public string EntityIdentifier { get; set; }
public List<Name> Names { get; set; }
}
public class Name
{
public string FullName { get; set; }
public string NameType { get; set; }
public bool CompareNameObjects(Name name2)
{
return FullName == name2.FullName &&
NameType == name2.NameType;
}
}
entities is a list of all my objects and I want to check if myEntity has any Names identical with another entity in the set.
EDITED:
The data structure is similar to the 2 classes (Entity and Name). The entities are created by selecting all the entities, along with their names, from the database in XML format and then I convert the XML to a List as such:
List<Entity> entities = new List<Entity>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["myCS"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("GetAllEntities", conn);
cmd.CommandType = CommandType.StoredProcedure;
string entitiesXml = "";
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
entitiesXml += rdr["XmlString"].ToString();
}
}
using (TextReader reader = new StringReader(entitiesXml))
entities = (Entity)xmlSerializer.Deserialize(reader);
conn.Close();
}
GetAllEntities (Stored Procedure):
declare @xmlString nvarchar(max) =(
select e.EntityIdentifier,
(
select n.[Full Name] as 'FullName',
n.[Name Type] as 'NameType'
from tblNames n
where e.EntityID=n.[Entity_ID]
for xml path('Name'), type
)
from tblEntities e
order by e.EntityID
for xml path('Entity')
)
select @xmlString as XmlString
linq ienumerable query-performance
|
show 1 more comment
up vote
0
down vote
favorite
I'm using LINQ to execute a query on a List type variable with a large amount of data (over a million). For performance purposes I'm using IEnumerable to store the results but when I try to access it there is a slight delay.
Specifically I want to see if the query produced any results, but when I use the .Count() or .Any() functions the performance drops.
I read that for IEnumerable types the execution of the query happens at the time of need, hence the delay. Is there a way to see if the IEnumerable has elements inside it without having that much delay?
This is what I'm trying to run.
IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.CompareNameObjects(n))));
and here are my classes
public class Entity
{
public string EntityIdentifier { get; set; }
public List<Name> Names { get; set; }
}
public class Name
{
public string FullName { get; set; }
public string NameType { get; set; }
public bool CompareNameObjects(Name name2)
{
return FullName == name2.FullName &&
NameType == name2.NameType;
}
}
entities is a list of all my objects and I want to check if myEntity has any Names identical with another entity in the set.
EDITED:
The data structure is similar to the 2 classes (Entity and Name). The entities are created by selecting all the entities, along with their names, from the database in XML format and then I convert the XML to a List as such:
List<Entity> entities = new List<Entity>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["myCS"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("GetAllEntities", conn);
cmd.CommandType = CommandType.StoredProcedure;
string entitiesXml = "";
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
entitiesXml += rdr["XmlString"].ToString();
}
}
using (TextReader reader = new StringReader(entitiesXml))
entities = (Entity)xmlSerializer.Deserialize(reader);
conn.Close();
}
GetAllEntities (Stored Procedure):
declare @xmlString nvarchar(max) =(
select e.EntityIdentifier,
(
select n.[Full Name] as 'FullName',
n.[Name Type] as 'NameType'
from tblNames n
where e.EntityID=n.[Entity_ID]
for xml path('Name'), type
)
from tblEntities e
order by e.EntityID
for xml path('Entity')
)
select @xmlString as XmlString
linq ienumerable query-performance
1
Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible
– Hieu Le
Nov 21 at 8:41
Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.
– Vasos Hadjioannou
Nov 21 at 8:45
You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));
– Hieu Le
Nov 21 at 9:00
Tried this but i get the same result
– Vasos Hadjioannou
Nov 21 at 9:14
I cannot tell you more if I don't know the table structures and what entities is
– Hieu Le
Nov 21 at 9:44
|
show 1 more comment
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm using LINQ to execute a query on a List type variable with a large amount of data (over a million). For performance purposes I'm using IEnumerable to store the results but when I try to access it there is a slight delay.
Specifically I want to see if the query produced any results, but when I use the .Count() or .Any() functions the performance drops.
I read that for IEnumerable types the execution of the query happens at the time of need, hence the delay. Is there a way to see if the IEnumerable has elements inside it without having that much delay?
This is what I'm trying to run.
IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.CompareNameObjects(n))));
and here are my classes
public class Entity
{
public string EntityIdentifier { get; set; }
public List<Name> Names { get; set; }
}
public class Name
{
public string FullName { get; set; }
public string NameType { get; set; }
public bool CompareNameObjects(Name name2)
{
return FullName == name2.FullName &&
NameType == name2.NameType;
}
}
entities is a list of all my objects and I want to check if myEntity has any Names identical with another entity in the set.
EDITED:
The data structure is similar to the 2 classes (Entity and Name). The entities are created by selecting all the entities, along with their names, from the database in XML format and then I convert the XML to a List as such:
List<Entity> entities = new List<Entity>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["myCS"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("GetAllEntities", conn);
cmd.CommandType = CommandType.StoredProcedure;
string entitiesXml = "";
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
entitiesXml += rdr["XmlString"].ToString();
}
}
using (TextReader reader = new StringReader(entitiesXml))
entities = (Entity)xmlSerializer.Deserialize(reader);
conn.Close();
}
GetAllEntities (Stored Procedure):
declare @xmlString nvarchar(max) =(
select e.EntityIdentifier,
(
select n.[Full Name] as 'FullName',
n.[Name Type] as 'NameType'
from tblNames n
where e.EntityID=n.[Entity_ID]
for xml path('Name'), type
)
from tblEntities e
order by e.EntityID
for xml path('Entity')
)
select @xmlString as XmlString
linq ienumerable query-performance
I'm using LINQ to execute a query on a List type variable with a large amount of data (over a million). For performance purposes I'm using IEnumerable to store the results but when I try to access it there is a slight delay.
Specifically I want to see if the query produced any results, but when I use the .Count() or .Any() functions the performance drops.
I read that for IEnumerable types the execution of the query happens at the time of need, hence the delay. Is there a way to see if the IEnumerable has elements inside it without having that much delay?
This is what I'm trying to run.
IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.CompareNameObjects(n))));
and here are my classes
public class Entity
{
public string EntityIdentifier { get; set; }
public List<Name> Names { get; set; }
}
public class Name
{
public string FullName { get; set; }
public string NameType { get; set; }
public bool CompareNameObjects(Name name2)
{
return FullName == name2.FullName &&
NameType == name2.NameType;
}
}
entities is a list of all my objects and I want to check if myEntity has any Names identical with another entity in the set.
EDITED:
The data structure is similar to the 2 classes (Entity and Name). The entities are created by selecting all the entities, along with their names, from the database in XML format and then I convert the XML to a List as such:
List<Entity> entities = new List<Entity>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["myCS"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("GetAllEntities", conn);
cmd.CommandType = CommandType.StoredProcedure;
string entitiesXml = "";
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
entitiesXml += rdr["XmlString"].ToString();
}
}
using (TextReader reader = new StringReader(entitiesXml))
entities = (Entity)xmlSerializer.Deserialize(reader);
conn.Close();
}
GetAllEntities (Stored Procedure):
declare @xmlString nvarchar(max) =(
select e.EntityIdentifier,
(
select n.[Full Name] as 'FullName',
n.[Name Type] as 'NameType'
from tblNames n
where e.EntityID=n.[Entity_ID]
for xml path('Name'), type
)
from tblEntities e
order by e.EntityID
for xml path('Entity')
)
select @xmlString as XmlString
linq ienumerable query-performance
linq ienumerable query-performance
edited Nov 21 at 10:17
asked Nov 21 at 8:36
Vasos Hadjioannou
11
11
1
Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible
– Hieu Le
Nov 21 at 8:41
Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.
– Vasos Hadjioannou
Nov 21 at 8:45
You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));
– Hieu Le
Nov 21 at 9:00
Tried this but i get the same result
– Vasos Hadjioannou
Nov 21 at 9:14
I cannot tell you more if I don't know the table structures and what entities is
– Hieu Le
Nov 21 at 9:44
|
show 1 more comment
1
Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible
– Hieu Le
Nov 21 at 8:41
Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.
– Vasos Hadjioannou
Nov 21 at 8:45
You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));
– Hieu Le
Nov 21 at 9:00
Tried this but i get the same result
– Vasos Hadjioannou
Nov 21 at 9:14
I cannot tell you more if I don't know the table structures and what entities is
– Hieu Le
Nov 21 at 9:44
1
1
Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible
– Hieu Le
Nov 21 at 8:41
Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible
– Hieu Le
Nov 21 at 8:41
Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.
– Vasos Hadjioannou
Nov 21 at 8:45
Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.
– Vasos Hadjioannou
Nov 21 at 8:45
You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));
– Hieu Le
Nov 21 at 9:00
You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));
– Hieu Le
Nov 21 at 9:00
Tried this but i get the same result
– Vasos Hadjioannou
Nov 21 at 9:14
Tried this but i get the same result
– Vasos Hadjioannou
Nov 21 at 9:14
I cannot tell you more if I don't know the table structures and what entities is
– Hieu Le
Nov 21 at 9:44
I cannot tell you more if I don't know the table structures and what entities is
– Hieu Le
Nov 21 at 9:44
|
show 1 more comment
1 Answer
1
active
oldest
votes
up vote
0
down vote
Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.
However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.
// Let's say you have myEntity here
var myEntity = new Entity();
var entities = new List<Entity>();
// You should prepare the list of name that you wanna to find before you do it so that you don't have to make it repeatedly for every iteration
var names = myEntity.Names.Select(p=> p.FullName + p.NameType ).ToDictionary(p=>p, p=>p);
IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => names.ContainsKey(n.FullName + n.NameType)));
This is just an example that may give you more idea. You can improve much more. I hope it can help you
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.
However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.
// Let's say you have myEntity here
var myEntity = new Entity();
var entities = new List<Entity>();
// You should prepare the list of name that you wanna to find before you do it so that you don't have to make it repeatedly for every iteration
var names = myEntity.Names.Select(p=> p.FullName + p.NameType ).ToDictionary(p=>p, p=>p);
IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => names.ContainsKey(n.FullName + n.NameType)));
This is just an example that may give you more idea. You can improve much more. I hope it can help you
add a comment |
up vote
0
down vote
Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.
However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.
// Let's say you have myEntity here
var myEntity = new Entity();
var entities = new List<Entity>();
// You should prepare the list of name that you wanna to find before you do it so that you don't have to make it repeatedly for every iteration
var names = myEntity.Names.Select(p=> p.FullName + p.NameType ).ToDictionary(p=>p, p=>p);
IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => names.ContainsKey(n.FullName + n.NameType)));
This is just an example that may give you more idea. You can improve much more. I hope it can help you
add a comment |
up vote
0
down vote
up vote
0
down vote
Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.
However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.
// Let's say you have myEntity here
var myEntity = new Entity();
var entities = new List<Entity>();
// You should prepare the list of name that you wanna to find before you do it so that you don't have to make it repeatedly for every iteration
var names = myEntity.Names.Select(p=> p.FullName + p.NameType ).ToDictionary(p=>p, p=>p);
IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => names.ContainsKey(n.FullName + n.NameType)));
This is just an example that may give you more idea. You can improve much more. I hope it can help you
Basically, you should avoid getting all data from your database then filter it with C# code. It consumes a lot of effort.
However, for quick solution, you can improve performance by preparing your conditions in a Dictionary form firstly.
// Let's say you have myEntity here
var myEntity = new Entity();
var entities = new List<Entity>();
// You should prepare the list of name that you wanna to find before you do it so that you don't have to make it repeatedly for every iteration
var names = myEntity.Names.Select(p=> p.FullName + p.NameType ).ToDictionary(p=>p, p=>p);
IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => names.ContainsKey(n.FullName + n.NameType)));
This is just an example that may give you more idea. You can improve much more. I hope it can help you
answered Nov 22 at 4:51
Hieu Le
529313
529313
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408060%2fperformance-issue-in-ienumerable-type-when-querying-large-amount-of-data-with-li%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Show us where "entities" is from. If you are using EF, to get the best performance, you should avoid using Enumerable as much as possible
– Hieu Le
Nov 21 at 8:41
Entities comes from a query on SQL Server. To get all the entities I have a small delay but I don't mind that.
– Vasos Hadjioannou
Nov 21 at 8:45
You cannot use CompareNameObjects in EF because it forces your code to run on RAM, not in SQL Server which is very slow. Please rephrase your condition to filter data directly. "Any" can be translated to SQL scripts, so no problem for it. Ex: entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.FullName == n.FullName && entityName.NameType == n.NameType)));
– Hieu Le
Nov 21 at 9:00
Tried this but i get the same result
– Vasos Hadjioannou
Nov 21 at 9:14
I cannot tell you more if I don't know the table structures and what entities is
– Hieu Le
Nov 21 at 9:44