LINQ para entidades Any () e Contains () lento com pequena lista

Estou usando o EF 6 para obter produtos de um banco de dados. As categorias de produtos são mapeadas como uma propriedade de navegação nos produtos e os dados são de uma tabela dinâmica ProductCategory. As categorias funcionam como uma árvore (ou seja, todas as categorias podem ter subcategorias), mas apenas o relacionamento mais específico de subcategoria de produto é armazenado na tabela dinâmica. Por exemplo, suponha que exista um caminho de categoria como este:

Eletrônica> Áudio> Amplificadores> Amplificadores Integrados.

Um produto que é um amplificador integrado possui um registro na tabela dinâmica com seu ID do produto e o ID da categoria de amplificadores integrados.

Preciso filtrar por categoria, mas o produto deve aparecer mesmo se filtrar por uma categoria principal, por exemplo um amplificador integrado deve aparecer em uma lista de amplificadores. Então, primeiro eu faço uma lista dos IDs de categoria relevantes. (Isso envolve uma consulta separada para a tabela de categorias, mas não demora muito.) Se o filtro de categoria for Amplificadores, a lista será o ID dos amplificadores e o ID dos amplificadores integrados.

O problema é que a consulta de produtos leva de 10 a 20 vezes mais quando eu incluo o filtro:

List<int> currentCategoryIdAndChildren = BuildCategoryIdList(currentCategoryId);

using (var db = new myContext())
{
    var products = db.Products
        .Select(p => new Product_PL
        {
            id = p.ID,
            name = p.Name,
            description = p.Description,
            categories = p.Categories
                        .Select(c => new Category_PL
                        {
                            categoryid = c.ID,
                        }),
        });

    // Filter by category
    products = products.Where(pl => pl.categories.Any(c => currentCategoryIdAndChildren.Contains(c.categoryid)));

    // Other filters, sorting, and paging here

    rptProducts.DataSource = products.ToList(); // Database call is made here
    rptProducts.DataBind();
}

Eu esperava que a combinação de Any () e Contains () diminuísse rapidamente com um grande número de registros, mas estou trabalhando com 22 itens em produtos, 1-3 itens em pl.categories e 1-5 itens em currentCategoryIdAndChildren . Estou surpreso que, com tão poucos registros, seja mais lento em uma ordem de magnitude. Nesse ritmo, é melhor filtrar o lado do cliente, mesmo que isso signifique trazer de volta muitos registros desnecessários.

Tem algo que estou perdendo? Existe outra abordagem?

ATUALIZAR: O Express Profiler relata que a consulta do banco de dados em si leva apenas 3ms, portanto, acho que o desempenho tem algo a ver com o funcionamento do Entity Framework. Certamente é mais lento na primeira vez em que o LINQ é executado (eu sei que ele precisa compilar a consulta), mas ainda é relativamente lento nas chamadas subseqüentes.

questionAnswers(2)

yourAnswerToTheQuestion