我陷入了這樣一個境地:我有數百萬條記錄,並且需要不同的連接來實現相同的記錄。訂單條款也有一些棘手的部分。如果我不應用任何排序,我的查詢會執行快速結果。但在應用 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注意:所有聯結都很重要,出於某些考慮,欄位已從選擇查詢中刪除。
解釋摘要
問題出在 LIMIT 和 ORDER BY 的組合。
如果沒有 ORDER BY,一旦選擇了前十個隨機行,查詢就會停止。依照 order by 查詢必須收集所有可能的行,然後按順序對它們進行排序,然後只傳回前 10 行。
考慮到「postponed_consultation_datetime」是一個計算字段,確實沒有辦法讓它更快。