设置MySQL中的数据类型来优化运行速度的实例_Mysql

今天看了一个优化案例觉的挺有代表性,这里记录下来做一个标记,来纪念一下随便的字段定义的问题。

回忆一下,在表的设计中很多人习惯的把表的结构设计成Varchar(64),Varchar(255)之类的,虽然大多数情况只存了5-15个字节.那么我看一下下面这个案例.
查询语句:
 

 SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = 1301 GROUP BY client_id, channel;

该表(client_id,channel)是一个组合索引.
利用explain,看一下执行计划,对于索引使用上看上非常完美
 

mysql> explain SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = 1301 GROUP BY client_id, channel;
+----+-------------+-------------+-------+--------------------+--------------------+---------+------+----------+--------------------------+
| id | select_type | table  | type | possible_keys  | key    | key_len | ref | rows  | Extra     |
+----+-------------+-------------+-------+--------------------+--------------------+---------+------+----------+--------------------------+
| 1 | SIMPLE  | xxx_sources | index | idx_client_channel | idx_client_channel | 1032 | NULL | 20207319 | Using where; Using index |
+----+-------------+-------------+-------+--------------------+--------------------+---------+------+----------+--------------------------+
1 row in set (0.00 sec)

看一下实际执行:
 

mysql> SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = 1301 GROUP BY client_id, channel;
+---------+----------+
| channel | visitors |
+---------+----------+
| NULL |  0 |
+---------+----------+
1 row in set (11.69 sec)

实际执行的情况非常的糟糕.传通的想法,这个执行从索引上执行计划上看非常完美了,好象和MySQL没什么关系了. 在去看一下表的设计会发现client_id也是设计成了
varchar(255).看到这里不防可以使用下面的方法试一下:

mysql> explain SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = '1301' GROUP BY client_id, channel;
+----+-------------+-------------+------+--------------------+--------------------+---------+-------+--------+--------------------------+
| id | select_type | table  | type | possible_keys  | key    | key_len | ref | rows | Extra     |
+----+-------------+-------------+------+--------------------+--------------------+---------+-------+--------+--------------------------+
| 1 | SIMPLE  | xxx_sources | ref | idx_client_channel | idx_client_channel | 258  | const | 457184 | Using where; Using index |
+----+-------------+-------------+------+--------------------+--------------------+---------+-------+--------+--------------------------+
1 row in set (0.00 sec)

从执行计划上来看,差不多,但实际差多了.具体上来看key_len从1032降到了258,执行计划变成了const基于等于的查找,行数从原来千万级到了十万级了.不算也能明白IO
节省了很多.
再来看实际执行:

 

mysql> SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = '1301' GROUP BY client_id, channel;
+---------+----------+
| channel | visitors |
+---------+----------+
| NULL |  0 |
+---------+----------+
1 row in set (0.25 sec)

哇,从11.69秒变成了0.25秒,这是什么概念,优化了多少倍,算一下吧.

看到这里在想什么呢,记住这个案例,嗯,不错,以后还可以加引号优化一下.那为什么不问一下,能不能在优化了,为什么会这样呢?
我们先来看一下第一个问题:
能不能在优化了?
答案是当然可以了.从索引的长度上来看258还是一个非常大的数据,对于client_id这个字段从名字上来看,也只会存数据型的值,那为什么不用的一个int unsigned去存呢,
索引的长度马上会从258降到4。这样不是又节省了很多吗?
接下来看一下第二个问题,为什么会这样呢?
原因有两点,同时基于一个原则,基于成本的优化器。对于client_id在表的定义时定义成了字符型的值,在查询时传入了数值型的值,需要经过一个数值转换,悲剧的开始,最终
导致MySQL选择了一个完成的索引去扫描。

从这个案例上,我们需要注意什么呢?
合理的选择数据类型,基本工太重要了,就这叫赢在起跑线,一切都不能随便了,别把一个表定义成了降了主建外其它全是Varchar(255)。对数据库的double/float这种字段做索引时一定要小心。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索mysql
mysql优化查询速度、mysql速度优化、ansys拓扑优化实例、matlab优化设计实例、abaqus拓扑优化实例,以便于您获取更多的相关知识。

时间: 2024-10-14 21:43:21

设置MySQL中的数据类型来优化运行速度的实例_Mysql的相关文章

MySQL中的数据类型

MySQL中的数据类型 详情请访问官网:http://dev.mysql.com/doc/refman/5.7/en/data-types.html   官方文档:http://dev.mysql.com/doc/refman/5.7/en/opengis-geometry-model.html   1.1  MySQL有哪些数据类型? MySQL中定义数据字段的类型对数据库的优化是非常重要的.MySQL支持多种类型,大致可以分为三类:数值.日期/时间和字符串(字符)类型.   1.数值类型 表

Android 开发中利用异步来优化运行速度和性能

本文讲的是Android 开发中利用异步来优化运行速度和性能, 我们知道,在Android框架中提供了很多异步处理的工具类.然而,他们中大部分实现是通过提供单一的后台线程来处理任务队列的.如果我们需要更多的后台线程的时候该怎么办呢? 大家都知道Android的UI更新是在UI线程中进行的(也称之为主线程).所以如果我们在UI线程中编写耗时任务都可能会阻塞UI线程更新UI.为了避免这种情况我们可以使用 AsyncTask, IntentService和Threads.在之前我写的一篇文章介绍了An

关于mysql中int数据类型储存最大数值与长度的关系

问题描述 关于mysql中int数据类型储存最大数值与长度的关系 关于mysql中int数据类型储存最大数值与长度的关系关于mysql中int数据类型储存最大数值与长度的关系关于mysql中int数据类型储存最大数值与长度的关系关于mysql中int数据类型储存最大数值与长度的关系 解决方案 int最大长度是11. 最大值是 2147483647 (2^31 – 1) 最小值是 -2,147,483,648(-2^31 ) 如果在建表时不指定字段int类型的长度时,系统则默认生成长度为11的字段

mysql中数据库索引与优化

一.索引的概念索引就是加快检索表中数据的方法.数据库的索引类似于书籍的索引.在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息.在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库. 二.索引的特点 1.索引可以加快数据库的检索速度 2.索引降低了数据库插入.修改.删除等维护任务的速度 3.索引创建在表上,不能创建在视图上 4.索引既可以直接创建,也可以间接创建 5.可以在优化隐藏中,使用索引 6.使用查询处理器执行SQL语句,在一个表上,一次只能使用一个索引

MySQL中CURRENT_TIMESTAMP数据类型详解

例 1. MySQL 获得当前时间戳函数:current_timestamp, current_timestamp()  代码如下 复制代码 mysql> select current_timestamp, current_timestamp(); +---------------------+---------------------+ | current_timestamp | current_timestamp() | +---------------------+------------

【请教】MySQL中的数据类型,从LONG变成了MEDIUMTEXT

问题描述 各位大师们: 我想用MySQL中的LONG类型,可是建表之后,系统默认给改成了MEDIUMTEXT,不知为何,请大师们指点迷津!谢过啦~~建表语句:CREATE TABLE testLong( id INT UNSIGNED NOT NULL AUTO_INCREMENT , number1 LONG NULL , PRIMARY KEY (`id`) );查看结果:DESC testlong;+---------+------------------+------+-----+---

解决MySQL中的Slave延迟问题的基本教程_Mysql

一.原因分析一般而言,slave相对master延迟较大,其根本原因就是slave上的复制线程没办法真正做到并发.简单说,在master上是并发模式(以InnoDB引擎为主)完成事务提交的,而在slave上,复制线程只有一个sql thread用于binlog的apply,所以难怪slave在高并发时会远落后master. ORACLE MySQL 5.6版本开始支持多线程复制,配置选项 slave_parallel_workers 即可实现在slave上多线程并发复制.不过,它只能支持一个实例

MySQL中基本的多表连接查询教程_Mysql

一.多表连接类型1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用','  如:         由于其返回的结果为被连接的两个数据表的乘积,因此当有WHERE, ON或USING条件的时候一般不建议使用,因为当数据表项目太多的时候,会非常慢.一般使用LEFT [OUTER] JOIN或者RIGHT [OUTER] JOIN  2.   内连接INNER JOIN 在MySQL中把I SELECT * FROM table1 CROSS J

MySQL中的唯一索引的简单学习教程_Mysql

mysql 唯一索引UNIQUE一般用于不重复数据字段了我们经常会在数据表中的id设置为唯一索引UNIQUE,下面我来介绍如何在mysql中使用唯一索引UNIQUE吧. 创建唯一索引的目的不是为了提高访问速度,而只是为了避免数据出现重复.唯一索引可以有多个但索引列的值必须唯一,索引列的值允许有空值.如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该使用关键字UNIQUE. 把它定义为一个唯一索引. 创建表时直接设置: DROP TABLE IF EXISTS `st