[英]Optimize MySQL query with range and multiple joins
我正在尋找優化下面的MySQL查詢。 是否有一個多列索引會更成功? 我沒有運氣嘗試過( created_date
, rep_id
)。 任何加快該查詢速度的建議都值得贊賞。
SELECT
customer.rep_id AS `ID`,
COUNT(*) AS Count,
rep.first_name,
rep.last_name
FROM customer
INNER JOIN appointment ON customer.id = appointment.customer_id
INNER JOIN rep ON customer.rep_id = rep.user_id
INNER JOIN user ON rep.user_id = user.id
WHERE customer.rep_id != 0
AND customer.saved = 0
AND customer.deleted = 0
AND customer.created_date >= '2017-01-01'
AND customer.created_date < '2017-02-01'
AND appointment.current = 1
AND appointment.realStatus IS NOT NULL
AND ( appointment.realStatus not in('rescheduled','cancelled')
OR (appointment.closed_by_id IS NULL
OR customer.rep_id != appointment.closed_by_id)
)
AND user.knocks = 1
AND user.deleted = 0
GROUP BY customer.rep_id
ORDER BY `Count` DESC
LIMIT 50
這是EXPLAIN
輸出:
id: 1
select_type: SIMPLE
table: customer
type: range
possible_keys: PRIMARY,rep_id,created_date
key: NULL
key_len: NULL
ref: NULL
rows: 354846
Extra: Using where; Using temporary; Using filesort
id: 1
select_type: SIMPLE
table: rep
type: ref
possible_keys: user_id
key: user_id
key_len: 4
ref: customer.rep_id
rows: 1
Extra: Using index condition
id: 1
select_type: SIMPLE
table: user
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: rep.user_id
rows: 1
Extra: Using where
id: 1
select_type: SIMPLE
table: appointment
type: ref
possible_keys: realStatus, customer_id, created_date
key: customer_id
key_len: 4
ref: customer.id
rows: 1
Extra: Using where
添加索引提示: from customer use index (created_date) inner join ...
(請注意, use index
並沒有執行它所說的;它只是使優化器忽略了您未提及的任何索引。)
除此之外,將約會customer_id索引設為(customer_id,current)
可能會有所幫助。
您可能需要復合索引-類似:
在客戶上創建多個索引(id,rep_id,created_date);
MySQL對每個表只使用一個索引(取決於版本,引擎等),如果它認為現有索引不會有幫助,則可以忽略它們。
我假設customer.saved和customer.deleted都是可能值很少的列-是/否,0/1等。查詢優化引擎往往會忽略它們。
稍微重寫了查詢,以提高可讀性和與聯接中其他表的視覺關聯。
SELECT
customer.rep_id AS `ID`,
COUNT(*) AS Count,
rep.first_name,
rep.last_name
FROM
customer
INNER JOIN appointment
ON customer.id = appointment.customer_id
AND appointment.current = 1
AND appointment.realStatus IS NOT NULL
INNER JOIN rep
ON customer.rep_id = rep.user_id
INNER JOIN user
ON rep.user_id = user.id
AND user.knocks = 1
AND user.deleted = 0
WHERE
customer.rep_id != 0
AND customer.saved = 0
AND customer.deleted = 0
AND customer.created_date >= '2017-01-01'
AND customer.created_date < '2017-02-01'
AND ( appointment.realStatus not in('rescheduled','cancelled')
OR ( appointment.closed_by_id IS NULL
OR customer.rep_id != appointment.closed_by_id ))
GROUP BY
customer.rep_id
ORDER BY
`Count` DESC
LIMIT
50
您可能需要多個復合索引來幫助查詢。 此外,我轉移了一些查詢元素以更好地匹配標准適用的地方(例如約會和用戶)。 這也有助於確定更好的索引選項。 也就是說,我將在每個索引上提供以下索引
table index
customer (saved, deleted, created_date, rep_id )
rep (user_id)
appointment (customer_id, current, realStatus)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.