Меня попросили сделать отчет, который объединяет 3 разных отчета о кристаллах, которые мы используем. Уже эти отчеты очень медленные и тяжелые, и о 1 большом не могло быть и речи. Так что я создал несколько приложений в VS 2010.
Моя главная проблема в том, что у меня есть 3 Datatable (та же схема), которые были созданы с помощью дизайнера наборов данных, которые мне нужно объединить. Я создал пустую таблицу для хранения объединенного значения. Запросы уже довольно большие, поэтому объединение их в запросе SQL действительно исключено.
Кроме того, у меня нет доступа на запись к SQL-серверу (2005), потому что этот сервер обслуживает компания, создавшая нашу программу MRP. Хотя я всегда могу обратиться в службу поддержки, чтобы добавить представление на сервер.
Итак, мои 3 данных состоят из стоимости рабочей силы, стоимости материалов и стоимости субподряда. Мне нужно создать таблицу общей стоимости, которая добавляет все столбцы стоимости каждой таблицы по идентификатору. Все таблицы имеют ключи, чтобы найти и выбрать их.
Проблема в том, что когда я получаю все текущее задание, все в порядке (500 мс для 400 записей), потому что у меня есть запрос, который будет извлекать только рабочее задание. Проблема с инвентаризацией, так как я не знаю, так как после того, как эти работы были завершены, я должен получить всю базу данных (около 10000 заданий с подзапросами, каждый из которых имеет до 100 записей), и это для моих 3 таблиц. Это занимает от 5000 до 8000 мс, хотя это очень быстро по сравнению с отчетом о кристаллах, есть одна проблема.
Мне нужно создать сводную таблицу, которая будет объединять все эти разные таблицы, которые я создал, но мне также нужно делать их 2 раза, по 1 разу для каждой выводимой даты. Так что мои данные всегда меняются, потому что они основаны на параметре Date. Прямо сейчас для их получения потребуется около 12-20 секунд.
Мне нужен способ сократить время загрузки, вот что я попробовал.
- Попытка цикла for объединить 3 таблицы
- Затем попытался с помощью класса DataReader прочитать каждую строку и использовал методы FindBy Key , созданные дизайнером набора данных, чтобы найти значение в другой таблице, и я должен сделать это 2 раза. (кажется, он идет немного быстрее, чем цикл for)
- Попробовал с Linq, не думаю, что это возможно, и даст ли он больше производительности?
- Попытка сделать динамический запрос, который использует "WHERE IN Comma Separated List " (который фактически удваивает время выполнения по сравнению с извлечением всей базы данных)
- Попытка присоединить мой запрос инвентаризации к запросам my Cost (что также увеличило время, затрачиваемое на это)
1 - Так есть ли способ объединить мои таблицы более эффективно? Какой самый быстрый способ объединения и суммирования моих записей 3 моих таблиц?
2 - Есть ли способ повысить производительность моих запросов, не имея права записи на сервер?
Ниже приведен код, который я использовал для справки:
public static void Fill()
{
DateTime Date = Data.Date;
AllieesDBTableAdapters.CoutMatTableAdapter mat = new AllieesDBTableAdapters.CoutMatTableAdapter();
AllieesDBTableAdapters.CoutLaborTableAdapter lab = new AllieesDBTableAdapters.CoutLaborTableAdapter();
AllieesDBTableAdapters.CoutSTTableAdapter st = new AllieesDBTableAdapters.CoutSTTableAdapter();
Data.allieesDB.CoutTOT.Clear();
//Around 2 sec each Fill
mat.FillUni(Data.allieesDB.CoutMat, Date);
Data.allieesDB.CoutMat.CopyToDataTable(Data.allieesDB.CoutTOT, LoadOption.OverwriteChanges);
lab.FillUni(Data.allieesDB.CoutLabor, Date);
MergeTable(Data.allieesDB.CoutLabor);
st.FillUni(Data.allieesDB.CoutST, Date);
MergeTable(Data.allieesDB.CoutST);
}
Вот методы MergeTable (цикл For, который я пробовал, находится в комментарии)
private static void MergeTable(DataTable Table)
{
AllieesDB.CoutTOTDataTable dtTOT = Data.allieesDB.CoutTOT;
DataTableReader r = new DataTableReader(Table);
while (r.Read())
{
DataRow drToT = dtTOT.FindByWO(r.GetValue(2).ToString());
if (drToT != null)
{
drToT["Cout"] = (decimal)drToT["Cout"] + (decimal)r.GetValue(3);
} else
{
EA_CoutsDesVentes.AllieesDB.CoutTOTRow row = dtTOT.NewCoutTOTRow();
for (int j = 0; j < r.FieldCount; j++)
{
if (r.GetValue(j) != null)
{
row[j] = r.GetValue(j);
} else
{
row[j] = null;
}
}
dtTOT.AddCoutTOTRow(row);
}
Application.DoEvents();
}
//try
//{
// for (int i = 0; i < Table.Rows.Count; i++)
// {
// DataRow drSource = Table.Rows[i];
// DataRow drToT = dtTOT.FindByWO(drSource["WO"].ToString());
//if (drToT != null)
//{
// drToT["Cout"] = (decimal)drToT["Cout"] + (decimal)drSource["Cout"];
//} else
//{
//
// EA_CoutsDesVentes.AllieesDB.CoutTOTRow row = dtTOT.NewCoutTOTRow();
// for (int j = 0; j < drSource.Table.Columns.Count; j++)
// {
// if (drSource[j] != null)
// {
// row[j] = drSource[j];
// } else
// {
// row[j] = null;
// }
// }
// dtTOT.AddCoutTOTRow(row);
//}
//Application.DoEvents();
// }
//} catch (Exception)
//{
//}