2017-02-05 3 views
0

У меня есть два запроса в моем коде:Могу ли я оптимизировать этот запрос дальше?

var query1 = (
     from c in db.HugeTableData 
     where c.price >= 1000 
     group c by new { c.year, c.month, c.day } into cgroup 
     select new { Count = cgroup.Count(), cgroup.Key }) 
    .OrderByDescending(x => x.Key.year).ThenByDescending(y => y.Key.month) 
    .ThenByDescending(z => z.Key.day).Take(50); 
//Some other code 
var query2 = (
    from c in db.HugeTableData 
    where c.price >= 1000 && c.check == true 
    group c by new { c.year, c.month, c.day } into cgroup 
    select new { Count = cgroup.Count(), cgroup.Key }) 
    .OrderByDescending(x => x.Key.year).ThenByDescending(y => y.Key.month) 
    .ThenByDescending(z => z.Key.day).Take(50); 

Это два запроса Получение квалифицированных записей из таблицы, которая имеет огромное количество данных, и, как вы видите, единственное различие между ними является && c.check == true часть, но я Я не ищу, как я могу его реорганизовать. К сожалению, этот код работает очень медленно, теперь мой вопрос: является ли низкая производительность, потому что два обратных перехода к базе данных? А также, если у меня есть огромные данные, то здесь хранится процедура?

EDIT: код, который использует эти запросы, как показано ниже:

foreach (var item in query1) 
{ 
    DateTime dt = Convert.ToDateTime(item.Key.year + "-" + item.Key.month + "-" + item.Key.day); 
    string temp = MyConvertToStringMethod(dt); 
    if (firstDictionary.ContainsKey(temp)) 
     firstDictionary[temp] = item.Count; 
} 

И еще один foreach для query2 похожее на это, чтобы заполнить secondDictionary.

+0

Можете ли вы показать код, который использует эти запросы? – Enigmativity

+0

@ Энигматичность ОК. Проверьте мой отредактированный вопрос. –

+0

@Enigmativity У вас есть идеи? –

ответ

0

Существует несколько подходов, которые вы можете предпринять здесь в зависимости от вашего сценария. Наиболее широко применимым было бы создание представления, которое реализует эту логику, а затем вы используете ее напрямую. В зависимости от ваших Dbms вы сможете ускорить этот подход, используя индексы. Альтернативно, если обработка результатов медленная, вы можете изучить использование ключевого слова C# yield при перечислении результатов, чтобы данные обрабатывались по мере их перечисления.

+0

Спасибо, но я уже использую индексы. Можете ли вы ответить на мои основные вопросы, как я спросил? является низкой производительностью, потому что два roundtrips в DataBase? А также, если у меня есть огромные данные, то здесь хранится процедура? –

+0

Я бы использовал представление лично, поскольку единственное различие - это поле проверки. Сервер Sql сможет создать план выполнения для этого представления, поэтому он должен работать быстрее после создания плана. Этот план будет использоваться для каждого последующего вызова для 50 строк. Также возможно создавать индексы на представлениях, которые также могут помочь. – Gavin

+0

А как насчет хранимой процедуры? Если у меня есть огромные данные, то здесь хранится процедура? –

1

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

var list = (
    from c in db.HugeTableData 
    where c.price >= 1000 
    group c by new { c.year, c.month, c.day , c.check } into cgroup 
    select new { 
    Count = cgroup.Count(), 
    cgroup.Key.year , 
    cgroup.Key.month, 
    cgroup.Key.day 
    }).ToList(); 

Затем вы можете выполнить linq- к объектам запросов

var query1 = (
    from c in list 
    group c by new { c.year, c.month, c.day } into cgroup 
    select new { Count = cgroup.Sum(), cgroup.Key }) 
.OrderByDescending(x => x.Key.year).ThenByDescending(y => y.Key.month) 
.ThenByDescending(z => z.Key.day).Take(50); 

var query2 = (
from c in list where c.check == true 
group c by new { c.year, c.month, c.day } into cgroup 
select new { Count = cgroup.Sum(), cgroup.Key }) 
.OrderByDescending(x => x.Key.year).ThenByDescending(y => y.Key.month) 
.ThenByDescending(z => z.Key.day).Take(50); 

// Обратите внимание, что вам нужно использовать Count=cgroup.Sum()