使用多列索引MYSQL进行优化

时间:2017-06-05 04:27:26

标签: mysql indexing query-optimization amazon-rds-aurora

寻找在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。

1 个答案:

答案 0 :(得分:3)

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

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列。然后,将在与A和B条件匹配的所有行上逐行应用列C的条件。

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

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

您可能会喜欢我的演示文稿How to Design Indexes, Really