复合索引顺序 MySQL 查询

Posted

技术标签:

【中文标题】复合索引顺序 MySQL 查询【英文标题】:Compound Index Order MySQL query 【发布时间】:2017-06-23 04:34:25 【问题描述】:

我正在尝试优化以下 mysql 查询。它运行大约 2.5 秒。我已经阅读了复合索引,但我希望有人可以帮助我了解您如何使用包含多个连接、许多条件(包括日期范围)、分组依据和排序依据的查询来订购复合索引一个计算值。我是否缺少有用的复合索引?有没有更有效的方法我应该从这些表中提取数据?非常感谢任何帮助!

SELECT 
branch.name AS branch,
SUM(appointment.status =  'completed') AS `Completed`, 
SUM(appointment.status =  'cancelled') AS `Cancelled`, 
SUM(appointment.status =  'not completed') AS `Not Completed`, 
SUM(appointment.status != 'rescheduled') AS `Total`
FROM rep
JOIN customer ON rep.id = customer.rep_id
JOIN office ON rep.office_id = office.id
JOIN appointment ON customer.id = appointment.customer_id
JOIN branch ON office.branch_id = branch.id
WHERE rep.active= 1 
AND rep.group IN (1,2,3) 
AND rep.deleted = 0 
AND customer.saved = 0 
AND (customer.rep_id != appointment.closed_by OR appointment.closed_by IS NULL)
AND customer.rep_id != 0 
AND customer.deleted = 0
AND office.visible = 1 
AND office.deleted = 0 
AND appointment.date >= '2016-12-01'
AND appointment.date < '2017-11-30' 
AND appointment.current = 1 
GROUP BY branch.id
ORDER BY Completed

这里是解释输出:

id: 1
select_type: simple
table: office
type: ref
possible_keys: PRIMARY, deleted_branchID_name, deleted_visible 
key: deleted_visible
key_len: 5
ref: const,const
rows:  73
Extra: Using index condition; Using temporary; Using filesort

id: 1
select_type: simple
table: branch
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: office.branch_id
rows: 1
Extra: NULL

id: 1
select_type:  simple
table: rep
type: ref
possible_keys: PRIMARY, group_id, office_id, active_deleted
key: office_id
key_len: 5
ref: office.id
rows:  57 
Extra: Using index condition; Using where

id:  1
select_type:  simple
table:  customer
type: ref
possible_keys: PRIMARY, rep_id
key: rep_id
key_len: 4
ref: rep.id
rows:  61 
Extra: Using where

id: 1
select_type: simple
table: appointment
type: ref
possible_keys: date, customer_id, closedByID_date, isCurrent_date
key: customer_id
key_len: 4
ref: customer.id
rows: 1
Extra: Using where

【问题讨论】:

在对您的数据一无所知的情况下,您的查询建议使用索引office(deleted, visible, branch_id)。然而,这个表似乎只包含少数几行,因此这个索引可能没有多大帮助;要选择更好的策略,您可以尝试识别强过滤器。如果例如99% 的数据将具有 customer.saved = 1appointment.current != 1,您可以尝试使用它来优化查询 - 但这取决于您的数据。此外,为了清楚起见,您应该用join 替换除最后一个left join 之外的所有内容(如果office.branch_idnot null,则最后一个也是) 【参考方案1】:

一个建议

根据条件删除无用的()

  LEFT JOIN customer ON rep.id = customer.rep_id
  LEFT JOIN office ON rep.office_id = office.id
  LEFT JOIN appointment ON customer.id = appointment.customer_id
  LEFT JOIN branch ON office.branch_id = branch.id

【讨论】:

以上是关于复合索引顺序 MySQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

#yyds干货盘点#MySQL索引优化系列:索引全用及最左法则

应该按哪个顺序(表列或查询)复合索引?

有关于mysql复合索引