【问题标题】:Different key_len results in same database (different enviroments)不同的 key_len 导致相同的数据库(不同的环境)
【发布时间】:2017-05-02 10:52:15
【问题描述】:

我在 AWS 中有一个生产数据库,但是 localhost 中的同一个数据库要快得多(25 秒 VS 7 秒),做一些研究我发现同一个 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
本地主机中的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 `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`)
)

【问题讨论】:

    标签: mysql amazon-web-services indexing explain


    【解决方案1】:

    解释 key_len 差异

    您发现在 5.6.4 中 DATETIMETIMESTAMP 发生的变化。之前,它们分别是 8 个字节(压缩十进制)和 4 个字节(只是一个INT)。之后它们都是 5+ 字节,包括最多包含 6 个小数位微秒的能力。

    “在哪里使用”并不意味着很多。 “使用索引条件”是指“ICP”或“索引条件下推”,这是一种优化,通常可以加速没有最佳复合索引的查询。 【此时需要看SHOW CREATE TABLE;我会猜测您正在使用 InnoDB。] 而不是将引擎 (InnoDB) 中的每一行“向上”传递给“处理程序”以进行进一步分析,“条件”(WHERE ...) 是将其“下推”到引擎,在那里可以更快地处理它。

    您的情况下,您将获得 3 至 4 倍的加速;好的。 (我的经验法则:2 倍。)

    其他

    你真的在做SELECT *吗?如果不需要所有的列,应拼出所需的列;您可能会错过一些优化潜力。

    UNIQ_848ABB8F2989F1FD 是“唯一的”,还是命名错误?

    如果invoice.numberUNIQUE,为什么不将它用作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
    

    【讨论】:

    • 非常感谢,非常有用的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多