none
Как ограничить выборку из связанной таблицы в Entity Framework RRS feed

  • Вопрос

  • Уважаемые Гуру!
    Есть таблица autos механизмов и подчиненная таблица с данными от gps - gpskadrs.
    За период накопилось порядка 100 000 записей измерений. Чтобы уменьшить время выборки , пробую
    ограничить выборку , скажем, 100 измерениями

    C#Выделить код
    1
    2
    
    IEnumerable<auto>  autoss = context.autos;
    List<gpskadr> k4 = autoss.ElementAt(i).gpskadrs.Take(100).ToList()
    Однако, время не уменьшается. Похоже всё равно выбираются все записи измерений.
    Возвращается указанное количество, но время остается таким, как если выбираются все записи.

    Как можно уменьшить время выборки?
    29 марта 2019 г. 11:40

Все ответы

  • IEnumerable<auto> вместе с ElementAt(i) приводит к тому, что из БД вытягивается полностью таблица autos, и уже на клиенте берется первое значение.

    IQueryable<auto> autoss = context.autos;
    List<gpskadr> k4 = autoss.First().gpskadrs.Take(100).ToList();

    Попробуйте так. IQueryable и First сгенерируют sql-запрос, который возьмет из БД одно значение.

    Take(100) должно работать, как и задумано.

    -----

    Сразу не разглядел: у вас i, а не 1 в ElementAt. Следовательно, этот код выполняется в цикле. Покажите больше кода, вместе с циклом.

    • Изменено Petalvik 30 марта 2019 г. 9:32
    30 марта 2019 г. 9:28
  • Вообще вопрос уже достаточно острый. 100 тыс записей это для одной машины в месяц, и это не самое большое. Всего за месяц более 15 млн записей. Вопрос масштабируемости уже не отложить на потом. Нет опыта как в принципе правильно решать вопрос. До какого размера таблицы можно наращивать базу? и т.п.

       Работаю с MySQL. 

    По поводу кода. Я чтобы оценить время работы с измерениями написал такой тест. Машин - порядка 250 , общий размер базы - около 15 млн.  измерений с широтой долготой и прочим. Кроме неудовлетворительного времени выборки , вылетала ошибка Out of Memory. Поэтому такой код

            private void button1_Click(object sender, EventArgs e)
            {
                List<autotechnodar> autoss;
                int k = 0;
                using (gpsEntities context = new gpsEntities())
                {
                    autoss = context.autotechnodars.ToList();
                }
                int count = 0;
                for (int i = 0; i < autoss.Count; i++)
                {
                    using (gpsEntities context = new gpsEntities())
                    {
                        int id =  autoss[i].id;
                        autotechnodar avto = context.autotechnodars.Where(c => c.id == id).FirstOrDefault();
                        k = avto.gpskadrs.Count();
                        count += k;
                    }
                    
                    nLabel.Text = i.ToString() + " Всего = "+count + " k = "+k;
                    this.Refresh();
                }
                MessageBox.Show("Всего записей "+count);
            }
     

    Этот блок выполнялся 12 минут.

    Саму выборку кадров измерений для выбранных машин делал так и записывал их в словарь машина - список измерений, чтобы последующие действия выполнялись быстро 

    IEnumerable<autotechnodar>  autoss = context.autotechnodars.Where(...);
    
    for (int i = 0; i < 6; i++ )
    {
       List<gpskadr> kadrs = 
         autoss.ElementAt(i).gpskadrs.Take(100).ToList();
    }



    • Изменено ATerentjev 1 апреля 2019 г. 7:00
    1 апреля 2019 г. 6:53