一个mysql优化技巧的误区

关于sql优化技巧,大家可能见过N个版本,尤其容易博得初中级程序员的眼球。倘若没有一点分析实践能力,直接将其拿来当作圣经记在心中并实践于工作中,那你极有可能被掉坑。轻则代码运行转圈圈无响应,重则导致项目瘫痪造成经济损失。

废话不多说,直接上图。

上面这条技巧粗略看一眼好像也没有什么问题。可事实是这样的吗?

结论当然是否定的。且看实例分析:

CREATE TABLE `t_auxiliary_info` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `ac_id` tinyint(3) unsigned NOT NULL COMMENT ‘分类ID‘,
  `name` varchar(250) NOT NULL DEFAULT ‘‘ COMMENT ‘名称‘,
  `number` smallint(6) unsigned NOT NULL DEFAULT ‘1‘ COMMENT ‘编号‘,
  `attr` varchar(500) NOT NULL DEFAULT ‘‘ COMMENT ‘属性‘,
  `fdbid` int(10) unsigned NOT NULL COMMENT ‘用户ID‘,
  `status` tinyint(1) unsigned NOT NULL DEFAULT ‘1‘ COMMENT ‘状态:1有效,0无效‘,
  `stock_type` tinyint(1) unsigned NOT NULL DEFAULT ‘0‘ COMMENT ‘存货类型:1库存商品,2原材料,3周转材料‘,
  PRIMARY KEY (`id`),#请注意这里的索引
  KEY `uniq_cid_acid` (`fdbid`,`ac_id`)
) ENGINE=InnoDB AUTO_INCREMENT=645101 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC

上面是一张普通的业务表,仔细看表中设置的索引:

  PRIMARY KEY (`id`),#主键索引
  KEY `uniq_cid_acid` (`fdbid`,`ac_id`)#联合索引

再使用上述的in 或not in 来实践以下,通过explain执行计划工具看看实际效果。(在这里为了公平起见,我不使用主键id,且in操作中的数据不是连续的。)

select * 
from t_auxiliary_info 
where fdbid in(‘1000‘,‘1500‘,‘1234‘,‘5155‘,‘6789‘,‘3423‘,‘5368‘,‘245645‘);
在上面的sql中,我们使用包含在联合索引`uniq_cid_acid`中的字段 `fdbid`作为搜索条件

见证奇迹的时刻到了。

通过执行计划, 我们可以清晰的看到这条sql的检索类型为简单简单检索,属于范围查询,且已经使用到了索引  uniq_cid_acid,且没有全表扫描(扫描行数为2804,而本表中数据条数为645101)。

        由此可以得出结论:不是所有sql中的in查询会全表扫描。这里推翻了in会导致全表扫描的结论。


        那么在什么情况下,使用in操作一样可以使用到索引,不会全表扫描呢?

        1.  in的字段必须是带有索引的字段。

        2.  in(...) 中的数据最好加上引号,即使字段类型是数字。


        在这里可能有人会有疑问,上面表中的字段fdbid是int类型,难道数值型的字段也需要用引号?我笑而不语。

select * 
from t_auxiliary_info 
where fdbid not in(1000,1500,1234,5155,6789,3423,5368,245645);

真相在这里:

这就是全表扫描!!!

所以最后给出的结论:

  1. 使用  in 条件的字段必须是索引字段。
  2. 且,in(。。。) 括号中的值都加上引号,无论字段类型是什么鬼。

欢迎讨论指教。

时间: 2024-11-05 22:57:33

一个mysql优化技巧的误区的相关文章

【转载:Mysql 优化】101个mysql优化技巧

MySQL是一个功能强大的开源数据库. 随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它的极限. 这里是101条调节和优化MySQL安装的技巧. 一些技巧是针对特定的安装环境的,但这些思路是通用的. 我已经把他们分成几类,来帮助你掌握更多MySQL的调节和优化技巧. MySQL 服务器硬件和操作系统调节: 1. 拥有足够的物理内存来把整个InnoDB文件加载到内存中--在内存中访问文件时的速度要比在硬盘中访问时快的多. 2. 不惜一切代价避免使用Swap交换分区 – 交换时是

日常工作中常见的mysql优化技巧

1.介绍一下MYSQL经常使用的优化技巧. MySQL 自带 slow log 的分析工具 mysqldumpslow ,可是没有说明.本文通过分析该脚本,介绍了其用法. slow log 是 MySQL 依据 SQL 语句的运行时间设定,写入的一个文件,用于分析运行较慢的语句. 仅仅要在 my.cnf 文件里配置好: log-slow-queries = [slow_query_log_filename] 就可以记录超过默认的 10s 运行时间的 SQL 语句. 假设要改动默认设置,能够加入:

项目中常用的19条MySQL优化技巧

原文:https://segmentfault.com/a/1190000012155267 声明一下:下面的优化方案都是基于 “ Mysql-索引-BTree类型 ” 的 一.EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划. 下面来个简单的示例,标注(1,2,3,4,5)我们要重点关注的数据 type列,连接类型.一个好的sql语句至少要达到range级别.杜绝出现all级别 key列,使用到的索引名.如果没有选择索引,值是NULL.可以采取强制索引方式 ke

mysql优化技巧

mysql 数据库优化 包括 a.表的设计合理化(符合3NF) b.添加适当索引(index[4种:普通索引 主键索引 唯一索引unique  全文索引]) c.分表技术(水平分割,垂直分割) d.读写[写:update/delete/add]分离 e.存储过程[模块化编程 可以提高速度] 数据库的三层结构 orale MySQL db2 sql server php程序通过dbms(数据库管理系统)操作数据库文件,数据库执行相关操作返回给dbms,然后再返回给PHP dbms 首先编译PHP代

MySQL十大优化技巧详解

1.优化你的MySQL查询缓存 在MySQL服务器上进行查询,可以启用高速查询缓存.让数据库引擎在后台悄悄的处理是提高性能的最有效方法之一.当同一个查询被执行多次时,如果结果是从缓存中提取,那是相当快的. 但主要的问题是,它是那么容易被隐藏起来以至于我们大多数程序员会忽略它.在有些处理任务中,我们实际上是可以阻止查询缓存工作的. // query cache does NOT work $r = mysql_query("SELECT username FROM user WHERE signu

一次mysql优化经历

某日运维突然说无线终端的频道页接口訪问量非常大,memcache缓存扛只是来.导致mysql并发查询量太大,导致server不停地宕机,仅仅能不停地重新启动机器.遗憾的是运维并没有告诉mysql查询量详细有多大[无量化,比方一秒多少个查询-]. 针对这个问题.有同事建议改了mysql+memcache的架构.採用redis存储更佳.可是问题的真正原因是什么呢?mysql一秒钟扛几百个并发查询应该是能够的吧?带着疑问.我让运维给出慢查询log. Oh,my god-慢查询记录太多,都是一秒钟以上的

MySQL通用优化技巧 | Ucloud运维在线微信群分享

MySQL通用优化技巧 | Ucloud运维在线微信群分享 2015-09-17 MySQL中文网 本文根据DevOps华南运维圈@UCloud微信群「大话运维」的嘉宾分享整理而成.「大话运维」将邀请业界运维前线技术专家作为分享嘉宾,分享技术趋势和技术实战,为运维朋友提供各种踩坑.躲坑.绕坑新技能. 嘉宾介绍 叶金荣Oracle MySQL ACE,国内最早的MySQL推广者.2006年创办国内首个MySQL专业技术网站 MySQL 中文网.资深MySQL专家,10余年MySQL经验,擅长Mys

【转】101个MySQL调试和优化技巧

MySQL是一个功能强大的开源数据库.随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它的极限.这里是101条调节和优化MySQL安装的技巧.一些技巧是针对特定的安装环境的,但这些思路是通用的.我已经把他们分成几类,来帮助你掌握更多MySQL的调节和优化技巧. MySQL 服务器硬件和操作系统调节: 1. 拥有足够的物理内存来把整个InnoDB文件加载到内存中——在内存中访问文件时的速度要比在硬盘中访问时快的多. 2. 不惜一切代价避免使用Swap交换分区 – 交换时是从硬盘读

mysql最好的优化技巧

mysql最好的优化技巧 发表于 2012-04-12 - 浏览:979 评论:0 收藏 0 1.选取最适用的字段属性 MySQL 可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小.例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了.同样的,如果可