我在AWS中有一个生产数据库,但localhost中的相同数据库更快(25秒VS 7s),做了一些研究我发现在同一个SQL中有一个差异:
EXPLAIN extended
SELECT *
FROM pipeline p
JOIN invoice i ON p.invoice_id = i.id
WHERE i.whenCreated BETWEEN "2017-01-01 00:00:00" AND "2017-01-31 00:00:00"
在AWS中=====> key_len = 8和Extra =使用where 在localhost ==> key_len = 5和Extra =使用索引条件。
我之前在两个网站上跑过:
OPTIMIZE TABLE invoice;
可能这是配置问题,但我迷路了。
更多信息:
AWS中的Mysql版本: 5.5.46
Localhost中的Mysql版本: 5.6.24
在AWS中解释:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: i
type: range
possible_keys: PRIMARY,IDX_5FD82ED84DD79520
key: IDX_5FD82ED84DD79520
key_len: 8
ref: NULL
rows: 847
filtered: 100.00
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: p
type: ref
possible_keys: UNIQ_848ABB8F2989F1FD
key: UNIQ_848ABB8F2989F1FD
key_len: 5
ref: ontrocrm.i.id
rows: 1
filtered: 100.00
Extra: Using where
在localhost中解释:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: i
type: range
possible_keys: PRIMARY,IDX_5FD82ED84DD79520
key: IDX_5FD82ED84DD79520
key_len: 5
ref: NULL
rows: 847
filtered: 100.00
Extra: Using index condition
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: p
type: ref
possible_keys: UNIQ_848ABB8F2989F1FD
key: UNIQ_848ABB8F2989F1FD
key_len: 5
ref: ontrocrm.i.id
rows: 1
filtered: 100.00
Extra: NULL
create table在两者中是相同的,一个是来自另一个的备份:
CREATE TABLE `invoice` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`number` int(11) NOT NULL,
`whenCreated` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_number` (`number`),
KEY `IDX_5FD82ED84DD79520` (`whenCreated`)
)
答案 0 :(得分:1)
解释key_len diff
您在5.6.4中发现了DATETIME
和TIMESTAMP
发生的更改。之前,它们分别是8个字节(压缩十进制)和4个字节(只是INT
)。之后它们都是5个字节,包括能够包含最多6位小数的微秒。
“使用where”并不意味着很多。 “使用索引条件”是指“ICP”或“索引条件下推”,这是通常加速没有最佳组合索引的查询的优化。 [此时,我需要看SHOW CREATE TABLE
;我将猜测您正在使用InnoDB。]而不是将每一行从引擎(InnoDB)传递回“向上”处理器以进行进一步分析,而不是'条件'(WHERE ...
)被“向下”推送到引擎,在那里它可以更快地处理。
在你的情况下,你获得3x-4x加速;不错。 (我的经验法则:2x。)
其他强>
你真的在做SELECT *
吗?如果您不需要所有列,则应拼出所需的列;你可能会遗漏一些优化潜力。
UNIQ_848ABB8F2989F1FD
是“独一无二的”,还是错误名称?
如果invoice.number
为UNIQUE
,为什么不将其用作PRIMARY KEY
并完全摆脱id
?这会加速一些操作(但是
可能不是当前的SELECT
)。
你可能注意到OPTIMIZE TABLE
几乎没有影响?
而不是WHERE i.whenCreated BETWEEN "2017-01-01 00:00:00" AND "2017-01-31 00:00:00"
,这需要额外的一秒,并且需要计算月末,我想说:
WHERE i.whenCreated >= "2017-01-01"
AND i.whenCreated < "2017-01-01" + INTERVAL 1 MONTH