【发布时间】:2018-03-06 04:25:47
【问题描述】:
我有以下查询,它使用带限制的 order by。提取大约 16k 数据需要 2 分 25 秒。我也做了正确的索引,但仍然执行缓慢。仅应用 LIMIT 20 时也需要相同的时间。删除 ORDER BY 后,查询会在 17 秒内获取相同的数据。所有表都在 latin1 字符集中。请提出任何可能的解决方案。
SELECT
a.customer,
a.division AS division,
a.noitaziraa_id AS noitaziraaId,
DATE_FORMAT(a.request_date, '%m/%d/%Y') AS RequestDate,
a.request_date AS RequestDateSort,
DATE_FORMAT(noita.date_of_birth, '%m/%d/%Y') AS dob,
noita.date_of_birth AS dobSort,
IF(
a.noita_type = 'Noita Stay',
a.length_of_stay,
NULL
) AS requestedDays,
IF(
a.noita_type = 'Noita Stay',
CONCAT_WS(
',',
a.facility_provider_city,
a.facility_provider_state
),
''
) AS facilityCityState,
IF(
a.noita_type = 'Noita Stay',
IFNULL(
DATE_FORMAT(aips.admission_date, '%m/%d/%Y'),
''
),
''
) AS admitDate,
IF(
a.noita_type = 'Noita Stay',
aips.admission_date,
''
) AS admitDateSort,
IF(
a.noita_type = 'Noita Stay',
IFNULL(
DATE_FORMAT(
aipsd.discharge_date,
'%m/%d/%Y'
),
''
),
''
) AS dischargeDate,
IF(
a.noita_type = 'Noita Stay',
aipsd.discharge_date,
''
) AS dischargeDateSort,
IF(
a.noita_type = 'Noita Stay',
IFNULL(dl1.`description`, ''),
''
) AS dischargeDisposition,
a.gender,
a.age,
a.relationship AS relationship,
noita.groupid,
a.request_type AS requestType,
a.prog_status AS programStatus,
dl.description AS billingDetails,
a.referred_to_npi AS NPI,
a.program AS program,
CASE
WHEN a.status = 'OPEN'
THEN DATEDIFF(NOW(), a.auth_request_date)
ELSE 0
END AS 'daysSinceRequest',
a.first_name AS firstName,
a.last_name AS lastName,
dl2.description AS levelOfUrgency,
a.member_id AS memberId,
a.created_full_name AS createdFullName,
CONCAT_WS(
',',
COALESCE(a.assigned_to, NULL),
COALESCE(
a.auth_review_assigned_user_name,
NULL
),
COALESCE(
a.auth_con_review_assigned_user_name,
NULL
),
COALESCE(a.assigned_queue, NULL),
COALESCE(
a.auth_review_assigned_queue_name,
NULL
),
COALESCE(
a.auth_con_review_assigned_queue_name,
NULL
)
) AS assignedTo,
a.status,
DATE_FORMAT(a.opened_date, '%m/%d/%Y') AS openDate,
a.opened_date AS openDateSort,
DATE_FORMAT(a.closed_date, '%m/%d/%Y') AS closedDate,
a.closed_date AS closedDateSort,
a.noita_type AS authType,
a.facility_provider AS facilityProvider,
a.length_of_stay AS lengthOfStay,
DATE_FORMAT(a.requested_from, '%m/%d/%Y') AS authFromDate,
a.requested_from AS authFromDateSort,
DATE_FORMAT(a.requested_through, '%m/%d/%Y') AS authToDate,
a.requested_through AS authToDateSort,
a.pended,
a.diagnosis AS diagnosis,
a.diagnosis_desc AS diagDesc,
a.auth,
a.denied,
a.excluded,
a.admit_type AS admitType,
a.service_type AS serviceType,
a.proc,
a.proc_desc AS procDesc,
a.plan
FROM
main_table a
INNER JOIN noitaciary noita
ON noita.id = a.noitaciary_id
INNER JOIN usermanagement.`user` usr
ON a.created_by = usr.id
AND
CASE
WHEN CONCAT(usr.firstname, ' ', usr.lastname) IN ('a', 'b *', 'c',
'd', 'd', 'f')
THEN 1 = 1
ELSE (
COALESCE(usr.`employer`, '') NOT IN ('r', 's')
)
END
LEFT JOIN noitaziraa_ips AS aips
ON aips.noitaziraa_id = a.auth_id
LEFT JOIN db1.`noitaziraa_history` ah
ON ah.noitaziraa_id = a.noitaziraa_id
LEFT JOIN noitaziraa_ips_discharge AS aipsd
ON aipsd.noitaziraa_ips_id = aips.id
LEFT JOIN noitaziraa_phr AS aphr
ON aphr.noitaziraa_id = a.auth_id
LEFT JOIN noitaziraa_sp AS asp
ON asp.noitaziraa_id = a.auth_id
LEFT JOIN noitaziraa_decisions AS auth_dec
ON a.auth_id = auth_dec.noitaziraa_id
LEFT JOIN mytable AS aa
ON a.noitaziraa_id = aa.noitaziraa_id
LEFT JOIN db1.dw_lookup dl
ON auth_dec.details = dl.code
LEFT JOIN db1.`dw_lookup` dl1
ON dl1.`code` = aipsd.`discharge_diposition`
AND dl1.`data_type` = 'dataTypeName'
LEFT JOIN db1.dw_lookup dl2
ON aa.level_of_urgency = dl2.code
AND dl2.data_type = 'dataTypeName1'
LEFT JOIN
(SELECT
*
FROM
(SELECT
hh.noitaziraa_id,
hh.`status`
FROM
db1.`noitaziraa_history` hh,
main_table a
WHERE hh.noitaziraa_id = a.noitaziraa_id
AND hh.client = 'certainValue'
AND DATE(hh.last_updated) < '2017-12-01 00:00:00'
GROUP BY hh.`last_updated`
ORDER BY hh.last_updated DESC) tmp
GROUP BY noitaziraa_id) AS tps
ON tps.noitaziraa_id = a.noitaziraa_id
WHERE a.customer LIKE 'certainValue%'
AND a.status <> 'VOID'
AND DATE(auth_dec.requested_through) >= '2017-12-01 00:00:00'
AND DATE(auth_dec.requested_through) <= '2017-12-05 00:00:00'
AND DATE(a.opened_date) <= '2017-12-05 00:00:00'
AND (
(
DATE(ah.last_updated) BETWEEN '2017-12-01 00:00:00'
AND '2017-12-05 00:00:00'
AND ah.status IN (
'OPEN',
'CLOSED',
'REOPENED',
'CANCELED'
)
) || (
tps.noitaziraa_id = a.noitaziraa_id
AND tps.status IN (
'OPEN',
'CLOSED',
'REOPENED',
'CANCELED'
)
)
)
GROUP BY a.auth_id
ORDER BY groupid ASC
LIMIT 0, 20
noitaziraa_history 表包含大量行,必须保持连接以满足我的要求,这需要花费大量时间。
【问题讨论】:
-
只是好奇 - COALESCE(x,NULL) 应该做什么?
-
另外,您似乎有一个没有关联聚合函数的 GROUP BY 子句。这不会影响性能,但会挑战任何结果的真实性。
-
@Strawberry COALESCE(x,NULL) 如果 x 为 null,则应该返回 NULL,否则返回 x 的值。你可以试试 SELECT COALESCE(NULL,21);和 SELECT COALESCE(1,NULL);
-
@Strawberry 我已经在我的 java 代码的查询中附加了 HAVING 子句。 :)
-
如果 x 为 null(否则 x 的值),x 也将返回 null。换句话说,你的 COALESCE 什么都不做。
标签: mysql select sql-order-by