b.d*_*igg 2 mysql indexing query-optimization amazon-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
Run Code Online (Sandbox Code Playgroud)
和 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'
Run Code Online (Sandbox Code Playgroud)
就上下文而言,总记录数:204,830。我的日期范围内的记录:65,491。
您应该使用不同顺序的列索引做得更好:
ALTER TABLE table_x ADD INDEX (serviceID, initialStatus, sales_date);
Run Code Online (Sandbox Code Playgroud)
The order of columns in the index is important. Your condition on sales_date is a range condition, i.e. it may match multiple values. Whereas the other two conditions on serviceID and initialStatus are equality conditions that match one value (or zero if the value is not found).
It's generally true that in an index lookup, all the equality conditions must be on columns that are leftmost in the multi-column index. Once a column of the index is used for a range condition, any further columns to the right in the index are not used.
Suppose an index on columns (A, B, C).
A condition like WHERE A=1 AND B=2 AND C=3 will use all three columns of the index.
A condition like WHERE A=1 AND B>2 AND C=3 will use only columns A and B in the index. Then the condition for column C will be applied, row-by-row, on all the rows that matched the A and B conditions.
A condition like WHERE A>1 AND B=2 AND C=3 will only use the first column on A for the index lookup.
The order of terms in your WHERE clause does not need to be the same as the order of columns in the index definition. MySQL knows how to rearrange the terms to match the column order.
You might like my presentation How to Design Indexes, Really.
| 归档时间: |
|
| 查看次数: |
1809 次 |
| 最近记录: |