Работают ли индексы с & ldquo; IN & rdquo; пункт

Пользовательский атрибут KinSlayerUY работал хорошо для меня, но у меня были проблемы с ComplexTypes. Они были сопоставлены как сущности в коде атрибута, поэтому не могли затем отображаться как ComplexType.

Поэтому я расширил код, чтобы это можно было сделать:

public static void OnModelCreating(DbModelBuilder modelBuilder)
    {
        foreach (Type classType in from t in Assembly.GetAssembly(typeof(DecimalPrecisionAttribute)).GetTypes()
                                   where t.IsClass && t.Namespace == "FA.f1rstval.Data"
                                   select t)
        {
            foreach (var propAttr in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<DecimalPrecisionAttribute>() != null).Select(
                   p => new { prop = p, attr = p.GetCustomAttribute<DecimalPrecisionAttribute>(true) }))
            {

                ParameterExpression param = ParameterExpression.Parameter(classType, "c");
                Expression property = Expression.Property(param, propAttr.prop.Name);
                LambdaExpression lambdaExpression = Expression.Lambda(property, true,
                                                                         new ParameterExpression[] { param });
                DecimalPropertyConfiguration decimalConfig;
                int MethodNum;
                if (propAttr.prop.PropertyType.IsGenericType && propAttr.prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    MethodNum = 7;
                }
                else
                {
                    MethodNum = 6;
                }

                //check if complextype
                if (classType.GetCustomAttribute<ComplexTypeAttribute>() != null)
                {
                    var complexConfig = modelBuilder.GetType().GetMethod("ComplexType").MakeGenericMethod(classType).Invoke(modelBuilder, null);
                    MethodInfo methodInfo = complexConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[MethodNum];
                    decimalConfig = methodInfo.Invoke(complexConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration;
                }
                else
                {
                    var entityConfig = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(classType).Invoke(modelBuilder, null);
                    MethodInfo methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[MethodNum];
                    decimalConfig = methodInfo.Invoke(entityConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration;
                }

                decimalConfig.HasPrecision(propAttr.attr.Precision, propAttr.attr.Scale);
            }
        }
    }
30
задан Joe Enos 14 November 2013 в 17:20
поделиться

5 ответов

Да, правильно. Если Ваш список сотрудников будет иметь 10 000 записей, и только 5 записей имеют employeetypeID в (1,2,3), то это будет, скорее всего, использовать индекс для выборки записей. Однако, если это находит, что 9 000 записей имеют employeeIDType в (1,2,3), тогда это, скорее всего, просто сделало бы сканирование таблицы для получения соответствующего EmployeeIDs, поскольку это быстрее только для пробежки целой таблицы, чем перейти к каждому ответвлению индексного дерева и посмотреть на записи индивидуально.

SQL Server делает много материала, чтобы попытаться оптимизировать как выполненные запросы. Однако иногда это не получает правильный ответ. Если Вы знаете, что SQL Server не использует индекс путем рассмотрения плана выполнения в запросе анализатор, можно сказать механизму запроса использовать определенный индекс со следующим изменением в запросе.

Select EmployeeId From Employee WITH (Index(Index_EmployeeTypeId )) Where EmployeeTypeId IN (1,2,3)

Принятие индекса, который Вы имеете на поле EmployeeTypeId, называют Index_EmployeeTypeId.

19
ответ дан bluish 14 November 2013 в 17:20
поделиться

Обычно это было бы, если В пункте не покроет слишком много таблицы, и затем это сделает сканирование таблицы. Лучший способ узнать в Вашем конкретном случае состоял бы в том, чтобы выполнить его в запросе анализатор и проверить план выполнения.

4
ответ дан Kibbee 14 November 2013 в 17:20
поделиться

@Mike: Спасибо за подробный анализ. Существуют определенно некоторые интересные замечания, которые Вы делаете там. Пример, который я отправил, несколько тривиален, но основание вопроса прибыло из использования NHibernate.

С NHibernate, можно записать пункт как это:

int[] employeeIds = new int[]{1, 5, 23463, 32523};
NHibernateSession.CreateCriteria(typeof(Employee))
.Add(Restrictions.InG("EmployeeId",employeeIds))

NHibernate тогда генерирует запрос, который похож

select * from employee where employeeid in (1, 5, 23463, 32523)

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

1
ответ дан lomaxx 14 November 2013 в 17:20
поделиться

, Таким образом, существует потенциал для "В" пункте для выполнения сканирования таблицы, но оптимизатор попытается разработать лучший способ иметь дело с ним?

, Используется ли индекс, не так варьируется на типе запроса такое количество типа и распределение данных в таблице (таблицах), насколько актуальный Ваши статистические данные таблицы, и фактический тип данных столбца.

другие плакаты корректны, что индекс будет использоваться за столом сканирование если:

  • запрос не получит доступ к больше, чем определенный процент индексированных строк (скажите ~10%, но должен варьироваться между DBMS).
  • , С другой стороны, если существует много строк, но относительно немного уникальных значений в столбце, это также может быть быстрее, чтобы сделать сканирование таблицы.

другая переменная, которая не могла бы быть настолько очевидной, удостоверяется, что типы данных сравниваемых значений являются тем же. В PostgreSQL я не думаю, что индексы будут использоваться, если Вы отфильтруете на плавании, но Ваш столбец составлен из ints. Существуют также некоторые операторы, которые не поддерживают индексное использование (снова, в PostgreSQL, оператор ILIKE похож на это).

, Как отмечено, хотя, всегда проверяйте анализатор запроса, когда в сомнении и документации Вашего DBMS будет Ваш друг.

2
ответ дан Dana the Sane 14 November 2013 в 17:20
поделиться
  • 1
    Это захватит значение первый выпадающий, не то, которое просто изменилось. – David Tang 2 February 2011 в 12:01

Если технология не улучшилась способами, которыми я не могу вообразить в последнее время, "В" показанном запросе приведет к результату, это - эффективно осуществление операции ИЛИ трех наборов результатов, один для каждого из значений в "В" списке. В пункте становится условием равенства для каждого списка и будет использовать индекс в подходящих случаях. В случае уникальных идентификаторов и достаточно большой таблицы тогда я ожидал бы, что оптимизатор будет использовать индекс.

, Если объекты в списке должны были быть групповыми однако, и я предполагаю в примере, что "Идентификатор типа" является внешним ключом, тогда я больше интересуюсь распределением. Я задаюсь вопросом, проверит ли оптимизатор статистику на каждое значение в списке? Скажите, что это проверяет первое значение и находит, что находится в 20% строк (достаточно большой таблицы для имения значение). Это будет, вероятно, сканирование таблицы. Но тот же план запросов будет использоваться для других двух, даже если они будут уникальны?

Это, вероятно, спорно - что-то как Список сотрудников, вероятно, будет достаточно маленьким, что это останется кэшируемым в памяти, и Вы, вероятно, не заметили бы различия между этим и индексированным извлечением так или иначе.

И наконец, в то время как я проповедую, остерегаются запроса в В пункте: это часто - быстрый способ получить что-то, что работа и (для меня, по крайней мере) может быть хорошим способом выразить требование, но об этом почти всегда лучше вновь заявляют как соединение. Ваш оптимизатор может быть достаточно умным для определения этого, но с другой стороны он не может. Если Вы в настоящее время не делаете производительности проверки по сравнению с производственными объемами данных, сделайте так - в эти дни оптимизации на основе издержек, Вы не можете быть уверены в плане запросов, пока у Вас нет предельной нагрузки и представительной статистики. Если Вы не можете, затем быть подготовленными к неожиданностям в производстве...

3
ответ дан Mike Woodhouse 14 November 2013 в 17:20
поделиться
  • 1
    Это было ответом, который работал на меня с Chrome.Спасибо. – Donal Fellows 15 April 2016 в 13:38
Другие вопросы по тегам:

Похожие вопросы: