使用多列索引进行优化 MYSQL

Optimize with Multi Column Index MYSQL

正在寻找优化 MySQL 中以下查询的方法。我已经尝试在 sales_date、serviceID 和 initalStatus 上创建多列索引,但它没有被使用。我曾尝试研究,但对优化不熟悉,似乎找不到合适的答案。下面是查询:

SELECT 
COUNT(id) as TotalAccounts,
AVG(sale_value) AS SaleValue,
AVG(credit_card = 1) * 100 AS CreditCard,
SUM(CASE WHEN pre_status = 1 AND bill_status = 'current' THEN 1 
ELSE 0
END) AS Active, 
SUM(CASE WHEN pre_status = 1 AND bill_status = 'past' THEN 1 
ELSE 0
END) AS PastDue, 
SUM(CASE WHEN `status` = 0 AND bill_status = 'past' THEN 1 
ELSE 0
END) AS Canceled
FROM table_x  
WHERE sales_date >= CAST('2015-01-01' AS DATE) 
AND sales_date <= CAST('2016-01-01' AS DATE)
AND serviceID = 1
AND initialStatus = 1 

以及 EXPLAIN 输出:

id:            '1',
select_type:   'SIMPLE',
table:         'table_x',
type:          'ALL', 
possible_keys: 'sales_date,Combo sales_date office_id,salesDate_serviceID_initalStatus', 
key:           NULL,
key_len:       NULL,
ref:           NULL,
rows:          '177585',
Extra:         'Using where'

对于上下文,总记录:204,830。我的日期范围内的记录:65,491。

您应该使用不同顺序的列索引做得更好:

ALTER TABLE table_x ADD INDEX (serviceID, initialStatus, sales_date);

索引中列的顺序很重要。您在 sales_date 上的条件是 范围条件 ,即它可能匹配多个值。而 serviceID 和 initialStatus 的其他两个条件是 相等条件 匹配一个值(如果未找到该值则为零)。

通常情况下,在索引查找中,所有相等条件都必须位于多列索引中最左边的列上。一旦索引的列用于范围条件,索引右侧的任何其他列都不会被使用。

假设列 (A, B, C) 上有一个索引。

WHERE A=1 AND B=2 AND C=3 这样的条件将使用索引的所有三列。

WHERE A=1 AND B>2 AND C=3 这样的条件将只使用索引中的 A 列和 B 列。然后,C 列的条件将逐行应用于所有符合 A 和 B 条件的行。

WHERE A>1 AND B=2 AND C=3 这样的条件只会使用 A 上的第一列进行索引查找。

WHERE 子句中术语的顺序不需要与索引定义中列的顺序相同。 MySQL 知道如何重新排列术语以匹配列顺序。

你可能会喜欢我的介绍How to Design Indexes, Really