سلام خدمت اساتید محترم

من دو تا جدول دارم که با چند شرط خاص می خوام کوئری بگیرم و سرعت بازیابی و نمایش اطلاعات خیلی مهم است زیرا برنامه تحت شبکه است.
دو جدول به نام TUser و TPardakht : فیلد UserId برای join دو جدول مشابه است.
حالا می خوام لیست کاربران (نام و نام خانوادگی از جدول TUser) و جمع مبلغ پرداختی مثلا در ماه 8 از جدول TPardakht مربوط به هر کاربر و آخرین تاریخ پرداختی در ماه 8 هر کاربر در یک جدول نمایش داده شود که :
1 - ممکن است در جدول TUser افرادی تعریف شده باشند که تا به حال هیچ پرداختی نداشته اند اما من می خواهم حداقل در جدول نام آنها را نشان دهد اما آخرین تاریخ پرداختی و مبلغ خالی باشد.
2 - افرادی که در ماه 9 پرداخت داشته اند را کلا نشان ندهد.
3 - جمع مبلغ پرداختی ماه 8 را می خواهم اما ستون بعدی فقط آخرین تاریخ پرداختی در ماه 8 را می خواهم. (بنابراین از group by نمیشه استفاده کرد)
4 - جمع کل مبلغ پرداختی از ابتدا تا کنون


تمامی اطلاعات می خواهم در یک دیتاتیبل ریخته شود.
من با دیتاتیبل و گذاشتن حلقه های تو در تو توانستم خروجی بگیرم اما سرعت بسیار بسیار پایین است. اساتید چه پیشنهادی می دهید؟ حالا یا با استفاده از join و یا linq

این کدها با حلقه های تو در تو:
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM TUser ORDER BY UserId ASC",                         conn = new SqlConnection(codes.ReturnConnectionstring()));
DataTable dt = new DataTable();
da.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++)
{
SqlDataAdapter daC = new SqlDataAdapter("SELECT * FROM TPardakht " +
"WHERE Month='9' AND UserId='" + dt.Rows[i]["UserId"].ToString() + "'",
conn = new SqlConnection(codes.ReturnConnectionstring()));
DataTable dtC = new DataTable();
daC.Fill(dtC);


//اگر کاربر پرداختی در ماه 9 نداشت اطلاعات ماه 8 را نشان بده
if (dtC.Rows.Count == 0)
{
SqlDataAdapter daa = new SqlDataAdapter("SELECT * FROM TPardakht " +
"WHERE Month='8' AND UserId='" + dt.Rows[i]["UserId"].ToString() + "'",
conn = new SqlConnection(codes.ReturnConnectionstring()));
DataTable dt2 = new DataTable();
daa.Fill(dt2);


string stLM = "", stLD = "", stLB = "";
decimal dMande = 0;


if (dt2.Rows.Count > 0)
{
decimal dM = 0;


if (dt2.Rows.Count > 0)
{
dM = 0;
for (int j = 0; j < dt2.Rows.Count; j++)
{
// جمع مبلغ پرداختی در ماه 8 و رشته فیلد توضیح هر کدام
dM += decimal.Parse(dt2.Rows[j]["Bed"].ToString());
stLB += dt2.Rows[j]["Babat"].ToString();


}
//آخرین تاریخ پرداختی در ماه 8
stLD = dt2.Rows[0]["Date"].ToString();
stLM = dM.ToString("N0");
}
//به دست آوردن جمع کل مبلغ پرداختی از اول تا کنون
dMande = 0;
SqlDataAdapter daM = new SqlDataAdapter("select isnull(sum(Bes),0)-isnull(sum(Bed),0) AS Mande from TPardakht " +
"where YCode='" + dt.Rows[i]["Code"].ToString() + "'",
conn = new SqlConnection(codes.ReturnConnectionstring()));
DataTable dtM = new DataTable();
daM.Fill(dtM);
dMande = decimal.Parse(dtM.Rows[0][0].ToString());




dtMandeList.Rows.Add("", dt.Rows[i]["UserId"].ToString(),
dt.Rows[i]["Name"].ToString(),
dMande, stLM, stLD, stLB, dt.Rows[i]["Code"].ToString());
}
}
}