2011-09-29 5 views
3

У меня есть запрос LINQ, который ищет таблицу SQL около 250 000 записей и выполняет поиск только по 2 полям. Оба поля были проиндексированы, но я считаю, что все еще работает довольно медленно.советы по ускорению запроса LINQ?

Ниже приведен код, может ли кто-нибудь предложить что-нибудь, чтобы ускорить его?

благодаря

var qryN = (
    from bn in dbs.Uploads 
    orderby bn.ID descending 
    select new 
    { 

     ID = bn.ID, 
     Serial = bn.serial_no, 
     Manufacturer = bn.Mfgr, 
     Model = bn.model, 
     Code = bn.code, 
     Qty = bn.qty, 
     Description = bn.description, 
     Comments = bn.comments, 
     Location = bn.location, 
     Price = bn.price, 
     Email = "Register/Login for full details" 
    }); 

if (dlType.Text != " " && dlType.Text != "") 
{ 
    qryN = qryN.Where(bn => bn.Manufacturer == dlType.SelectedValue); 
} 

if (txtWord.Text != "") 
{ 
    qryN = qryN.Where(bn => bn.Description.Contains(txtWord.Text)); 
    } 

gvLoggedOff.DataSource = 
    from p in qryN 
    select new 
    { 
     p.ID, 
     p.Serial, 
     p.Manufacturer, 
     p.Model, p.Code, 
     p.Qty, 
     p.Description, 
     p.Comments, 
     p.Location, 
     p.Price, 
     p.Email 
    }; 

gvLoggedOff.DataBind(); var qryN = (
    from bn in dbs.Uploads 
    orderby bn.ID descending 
    select new 
    { 

     ID = bn.ID, 
     Serial = bn.serial_no, 
     Manufacturer = bn.Mfgr, 
     Model = bn.model, 
     Code = bn.code, 
     Qty = bn.qty, 
     Description = bn.description, 
     Comments = bn.comments, 
     Location = bn.location, 
     Price = bn.price, 
     Email = "Register/Login for full details" 
    }); 

if (dlType.Text != " " && dlType.Text != "") 
{ 
    qryN = qryN.Where(bn => bn.Manufacturer == dlType.SelectedValue); 
} 

if (txtWord.Text != "") 
{ 
    qryN = qryN.Where(bn => bn.Description.Contains(txtWord.Text)); 
    } 

gvLoggedOff.DataSource = 
    from p in qryN 
    select new 
    { 
     p.ID, 
     p.Serial, 
     p.Manufacturer, 
     p.Model, p.Code, 
     p.Qty, 
     p.Description, 
     p.Comments, 
     p.Location, 
     p.Price, 
     p.Email 
    }; 

gvLoggedOff.DataBind(); 
+5

Вы посмотрели на сгенерированный SQL и профилировали его? –

+1

У 'Производитель' есть FK? –

+0

Джон абсолютно прав. Ваш вопрос в настоящее время очень расплывчатый. Мы не знаем, как выглядит модель данных, что вы создаете, используете ли вы LINQ to SQL, Entity Framework, NHibernate и т. Д. – Steven

ответ

1

две вещи:

  • Поскольку вы добавляете фильтры, перемещать проекцию (выбор в новый анонимный тип) к последней строке вместо первого, DataSource линия.
  • Вы заказываете очень рано. Если анализируемый запрос или анализатор запросов достаточно интеллектуальны, чтобы анализировать и оптимизировать его, база данных должна будет заказать 250 000 строк до начала фильтрации. Переместите заказ как можно дольше, возможно, непосредственно перед проецированием.

Вот короткая попытка модифицировать ваш образец:

var qryN = dbs.Uploads.AsQueryable(); 

if (dlType.Text != " " && dlType.Text != "") 
    qryN = qryN.Where(bn => bn.Mfgr == dlType.SelectedValue); 

if (txtWord.Text != "") 
    qryN = qryN.Where(bn => bn.description.Contains(txtWord.Text)); 

gvLoggedOff.DataSource = qryN.OrderByDescending(bn => bn.ID) 
    .Select(bn => new { 
     bn.ID, Serial = bn.serial_no, Manufacturer = bn.Mfgr, 
     Model = bn.model, Code = bn.code, Qty = bn.qty, 
     Description = bn.description, Comments = bn.comments, 
     Location = bn.location, Price = bn.price, 
     Email = "Register/Login for full details" }); 

gvLoggedOff.DataBind(); 

Так как это было принято в ответ: Steven's answer о поиске текста, вероятно, также применимы в некоторых ситуациях. Полный поиск текста может снизить производительность, как вы не поверите.

+0

yep, я действительно понимаю, но это то, чего хотел клиент. Я использовал ваше решение, а затем поставил Stevens на место для одного поля, и результаты отличные - еще раз спасибо – DarkW1nter

+0

@Pedro: О, конечно, я не говорю «не делай этого», я просто говорю «будьте в курсе Это". – Jesper

+0

одно небольшое дополнение: 'if (dlType.Text! =" "&& dlType.Text! =" ")' Может быть 'if (! String.IsNullOrWhiteSpace (dlType.Text))' –

7

Фильтр по Description может быть проблема:

qryN = qryN.Where(bn => bn.Description.Contains(txtWord.Text)); 

В Contains вызовов переводится в SQL description LIKE '%' + @p0 + '%'. Это означает, что даже если у вас есть индекс в столбце description, SQL-сервер должен перебрать полный индекс (или, возможно, даже полную таблицу). Если это возможно, измените строку следующим образом:

qryN = qryN.Where(bn => bn.Description.StartsWith(txtWord.Text)); 

Это приведет к description LIKE @p0 + '%' который позволяет сервер базы данных для эффективного использования индекса.

1

Description.Contains звучит тяжело, вы можете попробовать использовать полнотекстовый поиск.

Here - это сообщение, описывающее, как вы можете использовать FTS из LINQ.

Смежные вопросы