今天,我们看到了一个典型案例的最佳案例,它被记录为纪念临时领域定义问题的一个标志。

记得,在表的设计,许多人用来表的结构设计为varchar(64),varchar(255)等。虽然大多数情况下只保存5-15个字节,让我看一看下面的案例。

查询语句:






选择sql_no_cache通道(通道),计数从xxx_sources哪里client_id = 1301组游客。



表(client_id,通道)是一个综合指数。

利用解释并查看执行计划,这对索引的使用非常完美。






MySQL >解释选择sql_no_cache通道数(通道)为游客xxx_sources哪里。
+ -- + + + + ------------- ------------- ------- -------------------- + -------------------- + --------- + ------ ---------- -------------------------- + + +
我select_type表| | | |型possible_keys关键key_len | | | | REF |行|额外|
+ -- + + + + ------------- ------------- ------- -------------------- + -------------------- + --------- + ------ ---------- -------------------------- + + +
| 1 |简单| xxx_sources指数idx_client_channel idx_client_channel | | | | 1032 |空| 20207319 |使用;使用索引|
+ -- + + + + ------------- ------------- ------- -------------------- + -------------------- + --------- + ------ ---------- -------------------------- + + +
1行集(0秒)



查看实际执行情况。






MySQL >选择sql_no_cache通道数(通道)从xxx_sources哪里client_id = 1301游客。
--------- ---------- + + +
|通道|游客|
--------- ---------- + + +
|空| 0 |
--------- ---------- + + +
1行集(11.69秒)



实际执行情况非常糟糕。通过索引执行计划的想法非常完美。看来这与MySQL无关。什么时候去看表的设计,我们会发现,client_id也设计。

varchar(255)。请看这里不要用下面的方法来试试:


MySQL >解释选择sql_no_cache通道数(通道)为游客xxx_sources哪里。
+ -- + + + + ------------- ------------- ------ -------------------- + -------------------- + --------- + ------- -------- -------------------------- + + +
我select_type表| | | |型possible_keys关键key_len | | | | REF |行|额外|
+ -- + + + + ------------- ------------- ------ -------------------- + -------------------- + --------- + ------- -------- -------------------------- + + +
| 1 |简单| xxx_sources REF idx_client_channel idx_client_channel | | | | 258 | const | 457184 |使用;使用索引|
+ -- + + + + ------------- ------------- ------ -------------------- + -------------------- + --------- + ------- -------- -------------------------- + + +
1行集(0秒)




从执行计划来看,几乎是一样的,但实际情况更糟。详细的key_len从1032下降到258,而执行计划成为基于等搜索const。行数从一千万到十万级。它无法理解IO。

这是一笔很大的存款。

再看一下实际执行情况。






MySQL >选择sql_no_cache通道数(通道)从xxx_sources哪里client_id =游客;
--------- ---------- + + +
|通道|游客|
--------- ---------- + + +
|空| 0 |
--------- ---------- + + +
1行集(0.25秒)



哇,从11.69秒改到了0.25秒。它的概念是什么,它已经被优化了多少次

你觉得这里怎么样记住这个案子。是的,你可以稍后添加引号。你为什么不问问,它能被优化吗为什么

让我们看看第一个问题。

可以优化吗

答案当然是肯定的。从索引长度来看,258仍然是一个非常大的数据。为client_id领域,它将只存储其名称数据类型值。为什么不使用int符号来存储它呢

索引的长度将立即从258下降到4,这样可以节省更多吗

然后看看这两个问题,为什么会这样

有两个原因,同时,基于一个原则,基于成本的优化。在表client_id的定义,它被定义为字符的值,和值引入到查询。它需要一个数字变换,悲剧的开始,最后。

它会导致MySQL选择一个已完成的索引进行扫描。

从这件事我们需要注意什么

选择数据类型是合理的,基本的工作是非常重要的,它是赢在起跑线,什么都可以没有,不要把一个表定义为主体建筑,其他的是varchar的减少(255)。小心索引数据库的双/浮点字段。