通过MySQL表进行Linq查询花费的时间太长

时间:2019-05-21 16:50:05

标签: c# linq entity-framework-core

以下Linq查询联接6个以上的表,并创建一个'AppointmentData'列表。在联接内部,“约会”表和“患者”表具有最大的数据。 (预约约15,000,患者约5k)

执行此代码需要50秒钟。

IQueryable<Appointment> Appointments;

if (condition1)
{
    Appointments = _context.Appointment.Where(somecondition);
}
else
{
    Appointments = _context.Appointment.Where(othercondition);
}

AppointmentsData = (
    from 
        app in Appointments
    join 
        pat in _context.Patient
    on 
        app.IdPatient equals pat.Id
    join 
        doc in _context.Doctor
    on 
        app.IdDoctor equals doc.Id
    ...
    ...
    //* Around 5 more joins of the same type * // 
    ...

    select new Models.AppointmentData()
    {
        Id = app.Id,
        Patient = pat.FullName,
        Doctor = doc.FullName,
        ...
        ...
        ...
        /* around 15 more fields from different tables 
        that were joined */
        .....


    }
).ToList();

我尝试使用较小版本的数据库,该数据库具有约2k个约会和1k个患者,并且用时不到3秒。

我省略了一些条件,因为它们令人困惑,并且我确定它们与问题无关。

3 个答案:

答案 0 :(得分:0)

如果在MySQL工作台中运行生成的SQL,则可以看到其执行时间。您可以在工作台中分析查询后添加一些索引。

只需找到可以作为索引列的不错选择的列。您可以通过为查询添加一些索引来解决此问题。

答案 1 :(得分:0)

根据您的信息,我为您的挑战寻找了一些解决方案。

  1. 您可以尝试更改加入表格的方式(INNER JOIN,LEFT JOIN,...)。看here
  2. 您真的需要制作.ToList()吗?意思是你真的需要 评估结果集?尝试.AsEnumerable().AsQueryable()在上面的链接中进行了说明。
  3. 如果您使用的是EF,则可以尝试关闭“对象跟踪”。这个 检查结果集中的更改。这需要时间。
  4. 您还可以尝试使用子查询(不要将整个表与另一个整个表连接在一起。只需做出两个选择,将它们命名为X1和X2,然后通过其ID进行连接即可。

请原谅我,因为我4年前的最后一次使用EF不熟悉EF。

答案 2 :(得分:0)

首先,正如其他亲爱的成员所说,您应该检查列上是否有索引,然后尝试以下代码:

IQueryable<Appointment> Appointments;

        // Does not affect your slowness issue.
        Appointments = condition1 ? _context.Appointment.Where(somecondition) : _context.Appointment.Where(othercondition);

        AppointmentsData = Appointments
                           .Join(_context.Patient,
                                 appPatientKey => appPatientKey.Id, // The primary key of Appointments.
                                 patientKey => patientKey.Id,         // The primary key of Patient.
                                 (appPatientKey, patientKey) => new {
                                     Appointments = appPatientKey,
                                     Patient = patientKey
                                 })
                            .Join(_context.Doctor,
                                  appPatientKey => appPatientKey.IdDoctor, // Assuming that the IdDoctor is coming from Appointments
                                  doctorKey => doctorKey.Id,
                                  (appPatientKey, doctorKey) => new {
                                      appPatientKey.Appointments,
                                      appPatientKey.Patient,
                                      Doctor = doctorKey
                                  })
                            ... // other Joins
                            .GroupBy(result => { AppointmentId = result.Appointments.id, PatientFullName = result.Patient.Fullname, DoctorFullName = result.Doctor.FullName...})
                            .Select(theEntity => new Models.AppointmentData()
                            {
                                Id = AppointmentId,
                                Patient = PatientFullName,
                                Doctor = DoctorFullName

                            }).ToList();