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









share|improve this question




















  • 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

















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









share|improve this question




















  • 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















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









share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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
















  • 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














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






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    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

























    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






    share|improve this answer

























      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






      share|improve this answer























        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






        share|improve this answer












        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







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 4:51









        Hieu Le

        529313




        529313






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Berounka

            Sphinx de Gizeh

            Different font size/position of beamer's navigation symbols template's content depending on regular/plain...