MySQL常见注意事项及优化
MySQL常见注意事项
- 模糊查询 like 默认是对name字段建立了索引
注意:在使用模糊查询的时候,当% 在第一个字母的位置的时候,这个时候索引是无法被使用的。但是% 在其他的位置的时候,索引是可以被使用的。
# select * from tableName where name like "%zhangsan"; ?可以使用到索引啊? 不可以。
分析:因为是不确定查询,在表中任何一行记录都有可能满足查询条件。
#select * from tableName where name like "zh%"; 可以使用吗? 可以
#select * from tableName where name like "zh%三"; 可以使用吗? 可以
# select * from tableName where name like "z%san"; ? 可以使用吗?可以,首先可以快速定位z字母开头的部分。读z字母这段范围之内只能逐行比较。
- 对查询的列不要使用函数或者运算。否则索引无法使用。
# select * from tableName where id+1 = 1000;
# select * from tableName where id = 999; 等价。
有的时候,会在查询字段上面使用函数。使用函数的时候也是无法使用所有的,一般的解决方案是将查询后的结果交给php程序(字符串 和 数组)来实现处理。不要把函数的处理放在MySQL里面完成。
- 在你开发之中,什么样的字段适合建立索引?简述为什么?
答:
- 在where后面作为查询条件的字段是适合建立索引的。
- 注意:对于唯一很差的字段不适合建立索引,例如 只有 男 和 女 这两种情况的字段。
- 在需要排序的字段上面,也可以建立索引。
执行order by 不加限定,全表扫描,filesort含义 注意:问题?
- MySQL优化的一个通用方案?
答:
- 开启MySQL的慢查询记录功能,让系统运行一段时间(测试时间 都是在半个月到一个月时间)
- 检查慢查询的日志信息,分析出可能有问题的sql语句
- 使用profile工具详细去分析sql语句执行的时候,每个步骤所花费的时间,sending data(可能出现的问题 是MySQL没有使用索引的情况下,会去磁盘上获取数据:经验)
- 对sql语句优化(本身写出来的sql语句就存在问题,例如对查询的字段使用了函数)或者对表的结构(表中有些查询字段没有建立索引)适当的做一些调整(索引重建或者建立的更合适)
- 使用explain工具分析一下这些sql语句在执行的时候,是如何执行(可能使用索引或者是使用那些索引)
- type: const \ index \ 出现这些 代表索引正常使用
- 反复上面的过程具体分析。
- MySQL的自身缓存
解释:MySQL的客户端在发送sql语句到MySQL服务器端之后,会先去检查一下权限,之后去查询该条sql语句的缓存信息是否存在,如果存在,则直接返回;如果不存在,MySQL服务器需要去分析该sql语句,做词法语法分析,然后编译,生产执行树,去磁盘上获取数据,获取数据后,缓存到自身的一个缓存容器里面,然后在返回数据。
使用:
# show variables like "%cache%";
更改MySQL缓存的大小(32M),注意 单位是 B(字节)
# set global query_cache_size = 1024*1024*32;
注意:第一个是要加关键字 global 第二个是大小的单位为 B(字节) 第三具体给多少合适,取决于自身操作系统的内存大小。
测试对比:
注意:MySQL自身的缓存需要注意两点:
- MySQL的sql语句里面不能出现不确定信息(例如在条件里面使用 now()函数),MySQL的自身缓存将无法被使用。查询的结构不会被缓存起来。
分析:
- MySQL的自身的缓存是严格基于 sql 语句的(MySQL自身缓存是严格区分sql语句的大小写的) select === SELECT 关键字 其实是一样的
- MySQL的架构分析(读写分离)
由于一个网站业务中 70%的业务基本都是读操作,剩下的都是写操作。所以这个时候对读的压力过大,需要使用一定的方式来减少压力,这个时候可以使用读写分离这种架构来实现压力的分担。
怎么查询是读为主?
# show status like "%Com_%";
通过上面的分析一段时间,就可以大致计算出网站的读写情况
# show status ; 可以查看MySQL的一个状态信息。
读写分离概图:
mysql-proxy这个工具可以实现对sql语句的分析,判断sql语句是读操作(select关键字) 还是 写操作(insert、update、delete)。最后去连接不同的服务器实现业务的完成。
当完成读的时候,MySQL-proxy会从对台读服务器按照一定策略去选择一台(轮询、加权、ip_hash)完成读操作
当完成写的时候,直接去连接写的服务器
问题:
由于数据只在主服务器上实现写操作,但是从服务器上是没有完成写操作的,这个时候数据就会不一致。
需要解决一致性的问题?
答:可以使用MySQL的一个bin日志来完成数据的一致性问题。
使用步骤:
主服务器配置:
- 先在主服务器上开启bin日志(bin日志是MySQL的一个二进制日志功能,可以记录对MySQL数据造成更改的sql语句,形成一个日志文件)
- 在主服务器上的配置文件里面定义一个 server_id = Number 相当于标示一下这个服务器
- 在主服务器上添加一个授权账号用来到时候获取bin日志。
从服务器配置:
- 开启从服务器的一个中继日志,这个日志主要是把主服务器bin日志读取之后(无法直接使用,需要先转换为中继日志),形成转换。
- 在从服务器上的配置文件定义一个 server_id =Number 不要和主服务器重复
- 使用主服务器的授权账号去链接主服务器获取bin日志,然后读取到本地,形成中级日志,然后在本地的MySQL执行一遍,达到和主服务器上数据文件一致。
- 启动从服务器的主从复制功能。
总结:主从复制是完成读写分离的一个基础。(稍微有点延时)
优化技术
索引覆盖
对于MyISAM的存储引擎来说,如果查询的字段信息正好在索引文件里面出现,这个时候不需要做回行的操作,直接可以从索引文件里面返回的现象就叫做索引覆盖。(索引正好覆盖了查询的字段)
应用:在大数据(百万数据)下的一个翻页效果
技术点:翻页是如何做的?
答:select * from tableName limit offset,page;
好比现在是N页,每页显示page条
offset = (N-1) * page
实际使用:
分页操作
当很大页码的时候
通过上面的对比发现,MySQL在使用limit分页的时候,在页码足够大的情况下,效率是很低的,为什么?
答:主要原因是,MySQL在使用limit做查询的时候,如下sql:
select * from tableName limit offset,page;
执行过程:
先取出 offset+page 条记录, 然后在丢弃 offset 条记录 ,返回 page 条记录。
所以有必要对这种情况做优化操作:
- 从业务上完成(限制用户的行为,不允许翻页超过规定的页码)
百度限制用户行为:
- 不从限制用户的行为上去考虑,可以使用索引来实现。
- select * from tableName where id > Number limit page;
当分页页码变大的情况下:
通过使用 where id > Number limit 10; 这样由于可以使用上id的主键索引,所以可以快速的定位,达到一个大数据的分页的效果。
问题:
a. select * from tableName where id > Number limit page;
b. select * from tableName limit Number, page;
当上面的这两条sql语句执行后,结果在什么时候完全一致,什么时候不一致?
答:当数据没有被物理行删除的时候。这个时候数据是一致的,但是有物理行删除的时候,数据是不一致的。
如何解决上面的问题?
答:既然是物理行删除造成的,那就不做物理行的删除,只做逻辑删除(设置一个is_delete 字段 0 代表没有删除 1 代表已经删除)。
使用逻辑删除之后,数据会一致,只要在数据显示的,在显示层面(HTML)让is_delete=1 不显示出来即可。if( is_delete == 1) echo '该条信息已被删除!' 例如:常见的百度贴吧,网易新闻端。
3. 实现物理行删除,不限制用户行为
答:这个时候可以使用 索引覆盖 + 延时关联技巧 来实现。
分析:
程序代码实现:
在php层面实现
- 由于主键id是可以快速查找,先查出满足条件id
- 然后根据id快速的去查找对应的记录
foreach($data as $k=>$v){
$sql = select * from tableName where id = $v;
$res = mysql_query($sql);
$row = mysql_fetch_assoc($res);
$result[]= $row;
}
$result //分页数据
在MySQL层面联表处理:
使用联表来完成大数据的分页操作
解释
MySQL常见注意事项及优化的更多相关文章
- MySQL常见常用的SQL优化
应尽量避免在where中使用!=或<>操作符.否则会进行全表查询 对于查询,避免全盘扫描,考虑在where或order by涉及到的列上建立索引 避免在where中进行null值判断,否则 ...
- Mysql常见注意事项小记
1. 排序问题 正常如果按照某字段升序排列,空值会排到有值的前面;如果逆序排序空值排在最后. 有时候我们需要该字段为空的行数据要排到最后面去,这时只需要: order by second_parent ...
- MySQL常见优化
MySQL常见优化 1.操作符优化 1.1<> 操作符(不等于) 1.2LIKE优化 1.3in,not in,exists与not exists 1.3.1in和exists 2.whe ...
- mysql常见优化,更多mysql,Redis,memcached等文章
mysql常见优化 http://www.cnblogs.com/ggjucheng/archive/2012/11/07/2758058.html 更多mysql,Redis,memcached等文 ...
- 高性能MySql进化论(十一):常见查询语句的优化
总结一下常见查询语句的优化方式 1 COUNT 1. COUNT的作用 · COUNT(table.filed)统计的该字段非空值的记录行数 · ...
- MYSQL常见的可优化点
MYSQL常见的可优化点 SQL常见的可优化点 2014年6月8日 DBA 发表回复 # #################################################### 索引 ...
- Python进阶----索引原理,mysql常见的索引,索引的使用,索引的优化,不能命中索引的情况,explain执行计划,慢查询和慢日志, 多表联查优化
Python进阶----索引原理,mysql常见的索引,索引的使用,索引的优化,不能命中索引的情况,explain执行计划,慢查询和慢日志, 多表联查优化 一丶索引原理 什么是索引: 索引 ...
- 高性能MySQL学习总结二----常见数据类型选择及优化
一.数据类型的选择 MySQL的数据类型有很多种,选择正确的数据类型对于获得高性能特别地重要,如何选择合适的数据类型呢?主要遵从以下三个原则: 1.更小的通常情况下性能更好 一般情况下,应该尽量使用可 ...
- Mysql常见四种索引的使用
提到MySQL优化,索引优化是必不可少的.其中一种优化方式 --索引优化,添加合适的索引能够让项目的并发能力和抗压能力得到明显的提升. 我们知道项目性能的瓶颈主要是在"查(select)&q ...
随机推荐
- (ADO.NET)SqlCommand参数化查询
string strcon = "Persist Security Info=False;User id=sa;pwd=lovemary;database=student;server=(l ...
- Diycode开源项目 NodeListFragment分析
1.整体分析 1.1.作用讲解 这个类没有用到,只是一个备用的. 分类列表,用于定制首页内容 考虑到节点列表一般不会变化,所以直接将数据封装在客户端中,可以直接查看,提高效率. 1.2.整体分析 首先 ...
- iview框架 两侧弹框 出现第二层弹框 一闪而过的问题
分析原因:寡人怀疑可能是,两层弹出框 采用的是一个开关值,发生了覆盖 解决方式 是在第二层弹框外套层计时器 源代码如下: 修改后为:
- Python中bisect的使用方法
Python中列表(list)的实现其实是一个数组,当要查找某一个元素的时候时间复杂度是O(n),使用list.index()方法,但是随着数据量的上升,list.index()的性能也逐步下降,所以 ...
- S变换
哈哈,这两天在整理时频分析的方法,大部分参考网上写的比较好的资料,浅显易懂,在这谢过各位大神了! 今天准备写下S变换,由于网上资料较少,自己尝试总结下,学的不好,望各位多多指导 由前面的文章可知,傅里 ...
- 怎么使用瓦特平台下面的“代码工厂”快速生成BS程序代码
这里说一下怎么使用瓦特平台下面的“代码工厂”快速生成程序代码 使用平台:windows+"visual studio 2010"+"SqlServer2000+" ...
- IOS开发---菜鸟学习之路--(三)-数据解析
第三篇 上一篇我们讲了如何通过NSURL类来获取数据, 这一章我们来讲下对于获取过来的数据如何解析. 好了直接进入正文吧. 正文: 上一篇讲了 我们获取过来的数据格式是JSON格式的 大家可以搜下对应 ...
- 【Next Permutation】cpp
题目: Implement next permutation, which rearranges numbers into the lexicographically next greater per ...
- 详细的Windows下安装 binwalk
1. https://github.com/ReFirmLabs/binwalk到这里下载binwalk,下载后解压. 2. 找到下载后的文件夹, 在这里要进行安装步骤,一边按着shift,一边按着鼠 ...
- Java实现简单的socket通信
今天学习了一下java如何实现socket通信,感觉难点反而是在io上,因为java对socket封装已经很完善了. 今天代码花了整个晚上调试,主要原因是io的flush问题和命令行下如何运行具有pa ...