简体   繁体   English

对mysql表进行Linq查询需要太长时间

[英]Linq query over mysql table takes too long

The following Linq Query joins over 6 tables and creates a List of 'AppointmentData' . 以下Linq Query连接6个表并创建一个'AppointmentData'列表。 Inside the joins , 'Appointment' table and 'Patient' table has the largest data . 在连接内部,“约会”表和“患者”表具有最大的数据。 ( approx 15k for appointments and 5k for patients ) (预约约15k,患者约5k)

It's taking 50 seconds to execute this code. 执行此代码需要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();

I've tried using a smaller version of the database , with 2k appointments and 1k patients and it takes less than 3 seconds. 我尝试使用较小版本的数据库,2k约会和1k病人,只需不到3秒。

I have omitted a few conditions because they were confusing and I'm sure they're not related to the problem. 我省略了一些条件,因为它们令人困惑,我确信它们与问题无关。

If you run the generated SQL in MySQL workbench, you can see the time it take to execute. 如果在MySQL工作台中运行生成的SQL,则可以看到执行所需的时间。 You can add some index after analyzing the query in workbench. 您可以在分析工作台中的查询后添加一些索引。

Just find the column which can be good option for indexed column. 只需找到对于索引列可能是不错选项的列。 You can sort out this issue by adding some index for your query. 您可以通过为查询添加一些索引来解决此问题。

Based on your information I looked up some solutions for your challenge. 根据您的信息,我为您的挑战找到了一些解决方案。

  1. You can try to change the way your are joining the tables (INNER JOIN, LEFT JOIN, ...). 您可以尝试更改加入表格的方式(INNER JOIN,LEFT JOIN,...)。 Look here . 这里
  2. Do you really need to make a .ToList() ? 你真的需要制作.ToList()吗? Meaning do you really need a evaluated set of results? 意思是否真的需要一组经过评估的结果? Try .AsEnumerable() or .AsQueryable() described in the link above. 尝试上面的链接中描述的.AsEnumerable().AsQueryable()
  3. If you are using EF, you can try to turn off Object Tracking. 如果您使用的是EF,则可以尝试关闭对象跟踪。 This checks for changing in the result set. 这将检查结果集中的更改。 And this takes time. 这需要时间。
  4. You may also try to use sub-querys (don't join the whole table with another whole table. Just make two selects, name them as X1 and X2 and join them via their ID. 您也可以尝试使用子查询(不要将整个表与另一个整表连接起来。只需选择两个,将它们命名为X1和X2,然后通过它们的ID加入它们。

Please forgive me, that I'm not thaaat familiar with EF since I used it the last time 4 years ago. 请原谅我,自从我4年前最后一次使用EF以来,我并不熟悉EF。

First of all, as the other dear members said, you should check if you have indexes on the columns and then, try the following code: 首先,正如其他亲爱的成员所说,您应该检查列上是否有索引,然后尝试以下代码:

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM