I have this code, this code querying employee schedules in a month, in a work unit. If the List<Employee> count are few, the code works great, but if the List<Employee> count are many, the code runs slowly.  How I can optimize this code?The DataRow is datagrid row containing employee id, name, etc..await Task.Run(() =>{    List<Employee> employees = DatabaseHelper.GetEmployees(unitId, false, false);    for (int i = 0; i < employees.Count; i++)    {        int no = i + 1;        DataRow row = DataTableJadwal.Rows.Add(no + ., employees[i].Nama, employees[i].ID);        DatabaseHelper.GetUserSchedules(ref row, month, year);    }    Thread.Sleep(300);});public static void GetUserSchedules(ref DataRow row, int month, int year){    using (SqlConnection sqlConn = new SqlConnection(string.Format(constring, UserID, Password, Server, Database)))    {        using (SqlCommand sqlComm = new SqlCommand(            SELECT Date, Shift FROM ScheduleList WHERE (ID = @ID) AND (MONTH(Date) = @Month) AND (YEAR(Date) = @Year)            , sqlConn))        {            try            {                sqlComm.Parameters.AddWithValue(@ID, row[ID]);                sqlComm.Parameters.AddWithValue(@Month, month);                sqlComm.Parameters.AddWithValue(@Year, year);                sqlConn.Open();                using (SqlDataReader sqlReader = sqlComm.ExecuteReader())                {                    int totalHour = 0;                    while (sqlReader.Read())                    {                        DateTime dt = (DateTime)sqlReader[Date];                        string shift = (string)sqlReader[Shift];                        // a user may had 1,2,3 schedule a day                        string cellText = row[dt.Day.ToString(00)].ToString();                        if (cellText.Length < 1)                            cellText = shift;                        else                            cellText += , + shift;                        // count schedule hour total                        if (Utilities.FreeScheduleList.IndexOf(shift.ToUpper()) == -1)                        {                            if (shift == M || shift == Q)                                totalHour += 10;                            else                                totalHour += 7;                        }                        row[dt.Day.ToString(00)] = cellText;                    }                    row[Total] = totalHour;                }            }            catch (Exception ex)            {                MessageBoxEx.Show(ex.Message, GetUserSchedules Error, MessageBoxButton.OK, MessageBoxImage.Stop);            }        }    }}
Querying employee schedules in a month
c#;performance;beginner;sql server;.net datatable
First, create index on your table as @RobH suggestionCREATE INDEX IX_ScheduleList_Id_Date on your_schema.ScheduleList(    Id,    Date,    Shift)Then as @Paparazzi suggestion change your query so you only need to call it once, SELECT e.ID, nama, Date, Shift   FROM Employee e   JOIN ScheduleList s    ON s.ID = e.ID   AND e.unitId = @UnitId   AND s.Date >= @StartDate    AND s.Date < @AndDateThen filter the result in your code, it should be something like this.while (sqlReader.Read()){    string ID = sqlReader.GetString(0);    var rows = dataTable.AsEnumerable().Where(r => r.Field<string>(ID) == ID);    if (rows.Count() < 1)    {        // add row if row is not exist        num += 1;        string Nama = sqlReader.GetString(1);        row = dataTable.Rows.Add(num + ., Nama, ID);        row[Total] = 0;    }    else { row = rows.First(); }    // YOUR CODE    // ....}Don't forget to pass the DataTable, not the DataRowawait Task.Run(() =>{    DatabaseHelper.GetEmployeeAndSchedules(ref DataTable, unitId, month, year);    Thread.Sleep(300);});