mysql系列七、mysql索引优化、搜索引擎选择
一、建立适当的索引
说起提高数据库性能,索引是最物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行个正确的'create index',查询速度就可能提高百倍千倍,这可真有诱惑力。可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作, 增加了大量的I/O。
是不是建立一个索引就能解决所有的问题?ename上没有建立索引会怎样?
select * from emp where ename='研发部';
---测试案例命令如下 (最好以 select * from emp e,dept d where e.empno=123451 )
*添加主键
ALTER TABLE emp ADD PRIMARY KEY(empno);
*删除主键
alter table emp drop primary key;
二、索引的原理说明
没有索引为什么会慢?
使用索引为什么会快?
btree类型的索引,就是使用的二分查找法,肯定快啊,算法复杂度是log2N,也就是说16条数据查4次,32条数据查5次,64条数据查6次....依次类推
索引的代价
1、磁盘占用
2、对dml(update delete insert)语句的效率影响
btree 方式检索,算法复杂度: log2N 次数
三、哪些列上适合添加索引
1、较频繁的作为查询条件字段应该创建索引
select * from emp where empno = 1;
2、唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
select * from emp where sex = '男'
3、更新非常频繁的字段不适合创建索引
select * from emp where logincount = 1
4、不会出现在WHERE子句中的字段不该创建索引
四、索引的类型
- 主键索引,主键自动的为主索引 (类型Primary)
- 唯一索引 (UNIQUE)
- 普通索引 (INDEX)
- 全文索引 (FULLTEXT) [适用于MyISAM] ——》sphinx + 中文分词 coreseek [sphinx 的中文版 ]
- 综合使用=>复合索引
1、简述mysql四种索引的区别
lPRIMARY 索引 =》在主键上自动创建
lUNIQUE 索引=> 只要是UNiQUE 就是Unique索引.(只能在字段内容不重复的情况下,才能创建唯一索引)
lINDEX 索引=>就是普通索引
lFULLTEXT => 只在MYISAM 存储引擎支持, 目的是全文索引,在内容系统中用的多, 在全英文网站用多(英文词独立). 中文数据不常用,意义不大,国内全文索引通常使用 sphinx来完成,全文索引只能在 char varchar text字段创建.
2、全文索引案例
1.创建表
create table news(id int , title varchar(32),con varchar(1024)) engine=MyISAM;
2.建立全文索引
create fulltext index ful_inx on news (con);
3.插入数据
这里要注意,对于常见的英文 fulltext 不会匹配,而且插入的语句本身是正确的.
'but it often happens that they are not above supporting themselves by dishonest means.which should be more disreputable.Cultivate poverty like a garden herb'
4.看看匹配度
mysql> select match(con) against('poverty') from news; +-------------------------------+ | match(con) against('poverty') | +-------------------------------+ | 0 | | 0 | | 0 | | 0.9853024482727051 | +-------------------------------+
0表示没有匹配到,或者你的词是停止词,是不会建立索引的.
使用全文索引,不能使用like语句,这样就不会使用到全文索引了.
复合索引
create index 索引名 on 表名(列1,列2);
五、索引的使用
1、建立索引
create [UNIQUE|FULLTEXT] index index_name on tbl_name (col_name [(length)] [ASC | DESC] , …..);
alter table table_name ADD INDEX [index_name] (index_col_name,...)
添加主键(索引) ALTER TABLE 表名 ADD PRIMARY KEY(列名,..); 联合主键
2、删除索引
DROP INDEX index_name ON tbl_name;
alter table table_name drop index index_name;
删除主键(索引)比较特别: alter table t_b drop primary key;
查询索引(均可)
show index(es) from table_name;
show keys from table_name;
desc table_Name;
修改索引,我们一般是先删除在重新创建.
查询要使用索引最重要的条件是查询条件中需要使用索引。
3、下列几种情况下有可能使用到索引
1,对于创建的多列索引,只要查询条件使用了最左边的列,索引一般就会被使用。
2,对于使用like的查询,查询如果是 '%aaa' 不会使用到索引, 'aaa%'
会使用到索引。
4、下列的表将不使用索引
1,如果条件中有or,即使其中有条件带索引也不会使用。
2,对于多列索引,不是使用的第一部分,则不会使用索引。
3,like查询是以%开头
4,如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。(添加时,字符串必须'')
5,如果mysql估计使用全表扫描要比使用索引快,则不使用索引。
测试案例(就在前面的dept表上做演示.)
CREATE TABLE dept(
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
dname VARCHAR(20) NOT NULL DEFAULT "",
loc VARCHAR(13) NOT NULL DEFAULT ""
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
--放入数据,前面应该已经添加了,如果没有则需要重新添加
--测试开始.
添加一个主键索引
alter table dept add primary key (deptno)
--测试语句
explain select * from dept where deptno=1;
结果是:
mysql> explain select * from dept where deptno=1;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: dept
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 3
ref: const
rows: 1
Extra:
1 row in set (0.00 sec)
--创建多列索引
alter table dept add index myind (dname,loc);
--证明对于创建的多列索引,只要查询条件使用了最左边的列,索引一般就会被使用
explain select * from dept where dname='研发部'; 会显示使用到了索引myind
explain select * from dept where loc='MsBDpMRX'; 不会显示使用到了索引myind
--对于使用like的查询
explain select * from dept where dname like '%研发部'; 不会显示使用到了索引myind
explain select * from dept where dname like '研发部%'; 会显示使用到了索引myind
--如果条件中有or,即使其中有条件带索引也不会使用
--为了演示,我们把复合索引删除,然后只在dname上加入索引.
alter table dept drop index myind
alter table dept add index myind (dname)
explain select * from dept where dname='研发部' or loc='aa';-- 就不会使用到dname列上的
--如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引
select * from dept from dname=1234; //不会使用到索引
select * from dept from dname='1234'; //会使用到索引
查看索引的使用情况
show status like 'Handler_read%';
大家可以注意:
handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。
handler_read_rnd_next:这个值越高,说明查询低效。
* 这时我们会看到handler_read_rnd_next值很高,为什么,这是因为我们前面没有加索引的时候,做过多次查询的原因.
六、常用SQL优化
大批量插入数据(MySql管理员) 了解
对于MyISAM:
alter table table_name disable keys;
loading data//insert语句;
alter table table_name enable keys;
对于Innodb:
1,将要导入的数据按照主键排序
2,set
unique_checks=0,关闭唯一性校验。
3,set
autocommit=0,关闭自动提交。
优化group by 语句
默认情况,MySQL对所有的group by col1,col2进行排序。这与在查询中指定order by col1, col2类似。如果查询中包括group by但用户想要避免排序结果的消耗,则可以使用order by null禁止排序
有些情况下,可以使用连接来替代子查询。
因为使用join,MySQL不需要在内存中创建临时表。
如果想要在含有or的查询语句中利用索引,则or之间的每个条件列都必须用到索引,如果没有索引,则应该考虑增加索引
select * from 表名 where 条件1='' or 条件2='tt'
explaine select * from dept group by dname; =>这时显示 extra: using filesort 说明会进行排序
explaine select * from dept group by dname order by null =>这时不含有显示 extra: using filesort 说明不会进行排序
***有些情况下,可以使用连接来替代子查询。因为使用join,MySQL不需要在内存中创建临时表。
explain select * from emp , dept where emp.deptno=dept.deptno;
和下面比较就可以说明问题!!
explain select * from emp left join dept on emp.deptno=dept.deptno;
七、选择合适的存储引擎
- InnoDB:提供了具有提交、回滚和崩溃恢复能力的事务安全。但是对比MyISAM,写的处理效率差一些并且会占用更多的磁盘空间。
- Memory:数据存在内存中,服务重启时,数据丢失
- MyISAM: 在插入数据时,默认放在最后. ,删除数据后,空间不回收.(不支持事务和外键)。如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性要求不是很高。其优势是访问的速度快。
InnoDB 支持事务和外键
对应我们程序员说,常用的存储引擎主要是 myisam / innodb / memory,heap 表
如果选用小原则:
1.如果追求速度,不在乎数据是否一直把保存,也不考虑事务,请选择 memory 比如存放用户在线状态.
2.如果表的数据要持久保存,应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性要求不是很高。选用MyISAM
3.如果需要数据持久保存,并提供了具有提交、回滚和崩溃恢复能力的事务安全,请选用Innodb
八、选择合适的数据类型
在精度要求高的应用中,建议使用定点数来存储数值,以保证结果的准确性。deciaml 不要用float
对于存储引擎是MyISAM的数据库,如果经常做删除和修改记录的操作,要定时执行optimize table table_name;功能对表进行碎片整理。
日期类型要根据实际需要选择能够满足应用的最小存储的早期类型
create table bbs(id int ,con varchar(1024) , pub_time int);
date('Ymd',时间-3*24*60*60); 2038年-1-19
对于使用浮点数和定点数的案例说明
create table temp1( t1 float(10,2), t2 decimal(10,2));
insert into temp1 values(1000000.32,1000000,32); 发现 t1 成了 1000000.31 所以有问题.
对于optimize table 表名 演示
create table temp2( id int) engine=MyISAM;
insert into temp2 values(1); insert into temp2 values(2); insert into temp2 values(3);
insert into temp2 select * from temp2;--复制
delete from temp2 where id=1; 发现 该表对于的数据文件没有变小
定期执行 optimize table temp2 发现表大小变化,碎片整理完毕
&&对于InnoDB它的数据会存在data/ibdata1目录下,在data/数据库/只有一个 *.frm表结构文件.
mysql系列七、mysql索引优化、搜索引擎选择的更多相关文章
- 字符串可以这样加索引,你知吗?《死磕MySQL系列 七》
系列文章 三.MySQL强人"锁"难<死磕MySQL系列 三> 四.S 锁与 X 锁的爱恨情仇<死磕MySQL系列 四> 五.如何选择普通索引和唯一索引&l ...
- MySQL系列(七)--SQL优化的步骤
前面讲了如何设计数据库表结构.存储引擎.索引优化等内存,这篇文章会讲述如何进行SQL优化,也是面试中关于数据库肯定会被问到的, 这些内容不仅仅是为了面试,更重要的是付诸实践,最终用到工作当中 之前的M ...
- MySQL系列(九)--InnoDB索引原理
InnoDB在MySQL5.6版本后作为默认存储引擎,也是我们大部分场景要使用的,而InnoDB索引通过B+树实现,叫做B-tree索引.我们默认创建的 索引就是B-tree索引,所以理解B-tree ...
- MySql学习(七) —— 查询性能优化 深入理解MySql如何执行查询
本篇深入了解查询优化和服务器的内部机制,了解MySql如何执行特定查询,从中也可以知道如何更改查询执行计划,当我们深入理解MySql如何真正地执行查询,明白高效和低效的真正含义,在实际应用中就能扬长避 ...
- MySQL慢查询优化、索引优化、以及表等优化总结
MySQL优化概述 MySQL数据库常见的两个瓶颈是:CPU和I/O的瓶颈. CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据时候. 磁盘I/O瓶颈发生在装入数据远大于内存容量的时候,如果应 ...
- MySQL高级第二章——索引优化分析
一.SQL性能下降原因 1.等待时间长?执行时间长? 可能原因: 查询语句写的不行 索引失效(单值索引.复合索引) CREATE INDEX index_user_name ON user(name) ...
- MySQL系列(三)--数据库结构优化
良好的数据库逻辑设计和物理设计是数据库高性能的基础,所以对于数据库结构优化是很有必要的 数据库结构优化目的: 1.减少数据的冗余 2.尽量避免在数据插入.删除和更新异常 例如:有一张设计不得当的学生选 ...
- 阿里P8架构师谈:MySQL慢查询优化、索引优化、以及表等优化总结
更多内容:https://www.toutiao.com/i6599796228886626829/?tt_from=weixin&utm_campaign=client_share& ...
- MySQL调优之索引优化
一.索引基本知识 1.索引的优点 1.减少了服务器需要扫描的数据量 2.帮助服务器避免排序和临时表 例子: select * from emp orde by sal desc; 那么执行顺序: 所以 ...
- Mysql系列七:分库分表技术难题之分布式全局唯一id解决方案
一.前言 在前面的文章Mysql系列四:数据库分库分表基础理论中,已经说过分库分表需要应对的技术难题有如下几个: 1. 分布式全局唯一id 2. 分片规则和策略 3. 跨分片技术问题 4. 跨分片事物 ...
随机推荐
- bzoj1007/luogu3194 水平可见直线 (单调栈)
先按斜率从小到大排序,然后如果排在后面的点B和前面的点A的交点是P,那B会把A在P的右半段覆盖掉,A会把B在P的左半段覆盖掉. 然后如果我们现在又进来了一条线,它跟上一条的交点还在上一条和上上条的左边 ...
- Luogu 1437 [HNOI2004]敲砖块 (动态规划)
Luogu 1437 [HNOI2004]敲砖块 (动态规划) Description 在一个凹槽中放置了 n 层砖块.最上面的一层有n块砖,从上到下每层依次减少一块砖.每块砖都有一个分值,敲掉这块砖 ...
- 转载:Windows下stdlib.h与glut.h中exit()函数重复定义的解决方案
最近用到 OpenGL的第三方库Glut,碰到了exit()这个函数在stdlib.h与glut.h两个头文件中重复定义的情况,解决方案如下: 打开glut.h,找到exit()函数定义的地方(144 ...
- QQ企业邮箱+Spring+Javamail+ActiveMQ(发送企业邮件)
原来有个教程是关于Javamail的,但是那个是自己写Javamail的发送过程,这次不同的是:使用Spring的Mail功能,使用了消息队列. 先看一下设想的场景 不过本文重点不是消息队列,而是使用 ...
- SVN 错误:Error validating server certificate for 'https://xxxxxxx':443... Mac os svn客户端证书验证缓存 解决
mac上的SVN今天突然间 不好使了 在进行SVN操作是报出警告信息 Error validating server certificate for 'https://xxxxxxx':443 - T ...
- python小demo-01: 线程池+多进程实现cpu密集型操作
起因: 公司有一个小项目,大概逻辑如下: 服务器A会不断向队列中push消息,消息主要内容是视频的地址,服务器B则需要不断从队列中pop消息,然后将该视频进行剪辑最终将剪辑后的视频保存到云服务器.个人 ...
- 20190311 Windows上ZooKeeper伪集群的实现
1. 复制并修改conf/zoo.cfg文件 以zoo1.cfg为例: dataDir=E:\\Develop\\zookeeper\\3.4.6\\zookeeper-3.4.6\\data1 da ...
- Java中Dom解析XML
DOM将整个XML文件加载到内存中,并构建出节点树:应用程序可以通过遍历节点树的方式来解析XML文件中的各个节点.属性等信息:这种方式便于对XML节点的添加修改等,而且解析也很方便,然后它比较耗费内存 ...
- Javaweb学习笔记——(一)——————进入html
1.html的简介 *什么是html? -HyperText Markup Language:超文本标记语言,网页语言 **超文本:超出文本的范畴,使用html可以轻松实现这些操作 **标记:html ...
- 列表视图QlistView
列表视图QlistView要配合setModel模型一起使用 例子一 QStringListModel() 字符串列表模型 import sys from PyQt5.QtWidgets impor ...