不同的 key_len 结果相同的数据库(不同的环境)
Different key_len results in same database (different enviroments)
我在 AWS 中有一个生产数据库,但本地主机中的相同数据库要快得多(25s 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.
In localhost ==> key_len = 5 and Extra = Using index condition.
我 运行 在两个站点之前:
OPTIMIZE TABLE invoice;
可能是配置问题,但我迷路了。
更多信息:
Mysql AWS 中的版本:5.5.46
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
在本地主机中解释:
*************************** 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`)
)
解释 key_len 差异
您发现了 5.6.4 中 DATETIME
和 TIMESTAMP
发生的变化。之前,它们分别是 8 个字节(压缩十进制)和 4 个字节(只是一个 INT
)。之后都是5+字节,包括最多可以包含6位小数位微秒。
"Using where"并不意味着很多。 "Using index condition" 指的是 "ICP" 或 "Index Condition Pushdown",这是一种优化, 通常 加速没有最佳复合索引的查询。 [此时,我需要看到SHOW CREATE TABLE
;我会 猜测 你正在使用 InnoDB。] 不是将每一行从引擎 (InnoDB) 传回 'up' 'handler' 以供进一步分析, 'condition' (WHERE ...
) 被推送 'down' 到引擎,在那里可以更快地处理它。
在您的案例中,您获得了 3 到 4 倍的加速;好的。 (我的经验法则:2 倍。)
其他
你真的在SELECT *
吗?如果不需要所有栏目,应拼出需要的栏目;您可能缺少一些优化潜力。
是UNIQ_848ABB8F2989F1FD
"unique",还是名字有误?
如果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
我在 AWS 中有一个生产数据库,但本地主机中的相同数据库要快得多(25s 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.
In localhost ==> key_len = 5 and Extra = Using index condition.
我 运行 在两个站点之前:
OPTIMIZE TABLE invoice;
可能是配置问题,但我迷路了。
更多信息:
Mysql AWS 中的版本:5.5.46
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
在本地主机中解释:
*************************** 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`)
)
解释 key_len 差异
您发现了 5.6.4 中 DATETIME
和 TIMESTAMP
发生的变化。之前,它们分别是 8 个字节(压缩十进制)和 4 个字节(只是一个 INT
)。之后都是5+字节,包括最多可以包含6位小数位微秒。
"Using where"并不意味着很多。 "Using index condition" 指的是 "ICP" 或 "Index Condition Pushdown",这是一种优化, 通常 加速没有最佳复合索引的查询。 [此时,我需要看到SHOW CREATE TABLE
;我会 猜测 你正在使用 InnoDB。] 不是将每一行从引擎 (InnoDB) 传回 'up' 'handler' 以供进一步分析, 'condition' (WHERE ...
) 被推送 'down' 到引擎,在那里可以更快地处理它。
在您的案例中,您获得了 3 到 4 倍的加速;好的。 (我的经验法则:2 倍。)
其他
你真的在SELECT *
吗?如果不需要所有栏目,应拼出需要的栏目;您可能缺少一些优化潜力。
是UNIQ_848ABB8F2989F1FD
"unique",还是名字有误?
如果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