LINQ to Entities Any () и Contains () медленно с небольшим списком

Я использую EF 6 для получения продуктов из базы данных. Категории продуктов отображаются как свойства навигации по продуктам, а данные взяты из сводной таблицы ProductCategory. Категории работают как дерево (т. Е. Каждая категория может иметь подкатегории), но в сводной таблице хранится только наиболее конкретное отношение продукт-подкатегория. Например, предположим, что есть путь категории:

Электроника> Аудио> Усилители> Интегрированные усилители.

Продукт, который является встроенным усилителем, имеет запись в сводной таблице с идентификатором продукта и идентификатором категории встроенных усилителей.

Мне нужно отфильтровать по категории, но продукт должен отображаться даже при фильтрации по родительской категории, например, интегрированный усилитель должен появиться в списке усилителей. Итак, сначала я делаю список соответствующих идентификаторов категорий. (Это включает в себя отдельный запрос к таблице категорий, но это не займет много времени.) Если в качестве фильтра категории выбран «Усилители», список представляет собой идентификатор усилителей и идентификатор встроенных усилителей.

Проблема в том, что запрос товаров в 10-20 раз дольше, когда я включаю фильтр:

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();
}

Я ожидаю, что комбинация Any () и Contains () быстро замедлится с большим количеством записей, но я работаю с 22 элементами в продуктах, 1-3 элементами в pl.categories и 1-5 элементами в currentCategoryIdAndChildren , Я удивлен, что с таким небольшим количеством записей это на порядок медленнее. В таком случае мне лучше отфильтровывать его на стороне клиента, хотя это означает, что нужно возвращать много ненужных записей.

Я что-то упускаю? Есть ли другой подход?

ОБНОВИТЬExpress Profiler сообщает, что сам запрос к базе данных занимает всего 3 мс, поэтому я предполагаю, что производительность как-то связана с тем, как работает Entity Framework. Конечно, он самый медленный в самый первый раз, когда запускается LINQ (я знаю, что он должен скомпилировать запрос), но он все еще относительно медленный при последующих вызовах.

Ответы на вопрос(2)

Ваш ответ на вопрос