查询中的 Order 子句花费了太多 MySQL 加载时间
P粉258788831
P粉258788831 2024-02-21 20:36:00
0
1
318

我陷入了这样一个境地:我有数百万条记录,并且需要不同的连接来实现相同的记录。订单条款也有一些棘手的部分。如果我不应用任何排序,我的查询会执行快速结果。但在应用 order 子句时,需要花费太多时间才能得到结果。

如果没有 Order 子句,则会导致 5-6 秒。

应用订单条款时,结果为 40-45

SELECT 
  forms_values.id,
  CASE
    WHEN forms_values.appointment_type = 2 
    AND user_patient_assinged_to_doctor.start_time IS NOT NULL 
    THEN 
    CASE
      WHEN patient_responded_tags_logs.tag_set_at IS NOT NULL 
      THEN 
      CASE
        WHEN UNIX_TIMESTAMP(
          CONVERT_TZ(
            patient_responded_tags_logs.tag_set_at,
            "+00:00",
            "-06:00"
          )
        ) > UNIX_TIMESTAMP(
          CONVERT_TZ(
            STR_TO_DATE(
              CONCAT(
                user_patient_assinged_to_doctor.date,
                " ",
                user_patient_assinged_to_doctor.start_time
              ),
              "%Y-%m-%d %h:%i %p"
            ),
            "+00:00",
            "-06:00"
          )
        ) 
        THEN UNIX_TIMESTAMP(
          CONVERT_TZ(
            patient_responded_tags_logs.tag_set_at,
            "+00:00",
            "-06:00"
          )
        ) 
        ELSE UNIX_TIMESTAMP(
          CONVERT_TZ(
            STR_TO_DATE(
              CONCAT(
                user_patient_assinged_to_doctor.date,
                " ",
                user_patient_assinged_to_doctor.start_time
              ),
              "%Y-%m-%d %h:%i %p"
            ),
            "+00:00",
            "-06:00"
          )
        ) 
      END 
      ELSE UNIX_TIMESTAMP(
        CONVERT_TZ(
          STR_TO_DATE(
            CONCAT(
              user_patient_assinged_to_doctor.date,
              " ",
              user_patient_assinged_to_doctor.start_time
            ),
            "%Y-%m-%d %h:%i %p"
          ),
          "+00:00",
          "-06:00"
        )
      ) 
    END 
    ELSE 
    CASE
      WHEN patient_responded_tags_logs.tag_set_at IS NOT NULL 
      THEN 
      CASE
        WHEN UNIX_TIMESTAMP(
          CONVERT_TZ(
            patient_responded_tags_logs.tag_set_at,
            "+00:00",
            "-06:00"
          )
        ) > UNIX_TIMESTAMP(forms_values.created_at) 
        THEN UNIX_TIMESTAMP(
          CONVERT_TZ(
            patient_responded_tags_logs.tag_set_at,
            "+00:00",
            "-06:00"
          )
        ) 
        ELSE UNIX_TIMESTAMP(forms_values.created_at) 
      END 
      ELSE UNIX_TIMESTAMP(forms_values.created_at) 
    END 
  END AS "consultation_date_time_ordering",
  CASE
    WHEN forms_values.appointment_type = 2 
    AND user_patient_assinged_to_doctor.start_time IS NOT NULL 
    THEN UNIX_TIMESTAMP(
      CONVERT_TZ(
        STR_TO_DATE(
          CONCAT(
            user_patient_assinged_to_doctor.date,
            " ",
            user_patient_assinged_to_doctor.start_time
          ),
          "%Y-%m-%d %h:%i %p"
        ),
        "+00:00",
        "-06:00"
      )
    ) 
    ELSE UNIX_TIMESTAMP(forms_values.created_at) 
  END AS "consultation_date_time" ,
  CASE
    WHEN forms_values.is_postpone = '1' 
    OR forms_values.is_completed = '8' 
    THEN 
    CASE
      WHEN UNIX_TIMESTAMP(
        CONVERT_TZ(
          STR_TO_DATE(
            CONCAT(UTC_DATE(), ' ', UTC_TIME()),
            '%Y-%m-%d %h:%i:%s'
          ),
          '+00:00',
          '-06:00'
        )
      ) < UNIX_TIMESTAMP(
        my_list_postpone.postponed_date
      ) 
      THEN 0 
      ELSE 1 
    END 
    ELSE 1 
  END AS "postponed_consultation_ordering"
FROM
  `forms_values` 
  LEFT JOIN `forms_values_completed_status_details` 
    ON `forms_values_completed_status_details`.`form_value_id` = `forms_values`.`id` 
  /*INNER JOIN `users` 
    ON `users`.`id` = `forms_values`.`patient_id` 
  LEFT JOIN `users` AS `doctors` 
    ON `doctors`.`id` = `forms_values`.`doctor_id`*/ 
  LEFT JOIN `user_patient_assinged_to_doctor` 
    ON `user_patient_assinged_to_doctor`.`form_value_id` = `forms_values`.`id` 
  INNER JOIN `states_countries` 
    ON `forms_values`.`state` = `states_countries`.`id` 
  LEFT JOIN `user_payment_history` 
    ON `user_payment_history`.`form_value_id` = `forms_values`.`id` 
  LEFT JOIN `emailed_tags_logs` 
    ON `emailed_tags_logs`.`form_value_id` = `forms_values`.`id` 
    AND `emailed_tags_logs`.`id` = 
    (SELECT 
      emailed_tags_logs.id 
    FROM
      emailed_tags_logs 
    WHERE emailed_tags_logs.form_value_id = forms_values.id 
      AND emailed_tags_logs.id = 
      (SELECT 
        emailed_tags_logs1.id AS emtid 
      FROM
        emailed_tags_logs AS emailed_tags_logs1 
      WHERE emailed_tags_logs1.form_value_id = forms_values.id 
      ORDER BY emailed_tags_logs1.created_at DESC 
      LIMIT 1) 
      AND emailed_tags_logs.status IN (1, 3) 
      AND emailed_tags_logs.is_pt_responded = "0" 
    ORDER BY emailed_tags_logs.created_at DESC 
    LIMIT 1) 
  LEFT JOIN `my_list_assign_doctor` 
    ON `my_list_assign_doctor`.`form_value_id` = `forms_values`.`id` 
    AND `my_list_assign_doctor`.`id` = 
    (SELECT 
      my_list_assign_doctor.id 
    FROM
      my_list_assign_doctor 
    WHERE my_list_assign_doctor.form_value_id = forms_values.id 
      AND my_list_assign_doctor.status IN (1, 2) 
      AND my_list_assign_doctor.prior_type = "others" 
    ORDER BY my_list_assign_doctor.created_at DESC 
    LIMIT 1) 
  LEFT JOIN `my_list_assign_doctor` AS `my_list_postpone` 
    ON `my_list_postpone`.`form_value_id` = `forms_values`.`id` 
    AND `forms_values`.`is_postpone` IN ('1', '2') 
    AND `my_list_postpone`.`id` = 
    (SELECT 
      my_list_assign_doctor.id 
    FROM
      my_list_assign_doctor 
    WHERE my_list_assign_doctor.form_value_id = forms_values.id 
      AND my_list_assign_doctor.prior_type = "postpone" 
    ORDER BY my_list_assign_doctor.created_at DESC 
    LIMIT 1) 
  LEFT JOIN `users` AS `partner` 
    ON `user_payment_history`.`std_partner_id` = `partner`.`id` 
  LEFT JOIN `patient_responded_tags_logs` 
    ON `patient_responded_tags_logs`.`form_value_id` = `forms_values`.`id` 
    AND `patient_responded_tags_logs`.`status` = '1' 
  LEFT JOIN `user_subscriptions` 
    ON `user_subscriptions`.`user_payment_history_id` = `user_payment_history`.`id` 
    AND `user_payment_history`.`form_value_id` = `forms_values`.`id` 
ORDER BY 
postponed_consultation_ordering DESC,
  `consultation_date_time` DESC 
LIMIT 10 OFFSET 0

注意:所有联接都很重要,出于某些考虑,字段已从选择查询中删除。

解释摘要

P粉258788831
P粉258788831

全部回复(1)
P粉182218860

问题出在 LIMIT 和 ORDER BY 的组合上。

如果没有 ORDER BY,一旦选择了前十个随机行,查询就会停止。按照 order by 查询必须收集所有可能的行,然后按顺序对它们进行排序,然后仅返回前 10 行。

考虑到“postponed_consultation_datetime”是一个计算字段,确实没有办法让它更快。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!