mysql语句的优化

61次阅读
没有评论

共计 4428 个字符,预计需要花费 12 分钟才能阅读完成。

本篇内容介绍了“mysql 语句的优化”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让丸趣 TV 小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

 
MySQL 客户端连接成功后,通过使用 show [session|global] status 命令可以提供服务器状态信息。
其中的 session 来表示当前的连接的统计结果,global 来表示自数据库上次启动至今的统计结果, 默认是 session 级别的。 

下面的例子:
show status like lsquo;Com_% rsquo;; 其中 Com_XXX 表示 XXX 语句所执行的次数. 重点注意:Com_select,Com_insert,Com_update,Com_delete 通过这几个参数,
可以容易地了解到当前数据库的应用是以插入更新为主还是以查询操作为主,以及各类的 SQL 大致的执行比例是多少。
 
还有几个常用的参数便于用户了解数据库的基本情况。
Connections:试图连接 MySQL 服务器的次数 show status like Connections
Uptime:服务器工作的时间(单位秒)show status like Uptime
Slow_queries:慢查询的次数 (默认是 10) show status like lsquo;Slow_queries rsquo;
如何查询 mysql 的慢查询时间
Show variables like long_query_time
修改 mysql 慢查询时间
set long_query_time=2
 
*** 如何定位慢查询
Show variables like long_query_time
可以重新设置 set long_query_time=2 
**** 测试语句 ***
select * from emp e,dept d where e.empno=123451  and e.deptno=d.deptno; 
如果带上 order by e.empno 速度就会更慢,有时会到 1min 多.
**** 在默认情况下 mysql 不记录慢查询日志,需要在启动的时候指定 bin\mysqld.exe – -slow-query-log
该慢查询日志会放在 data 目录下 [在 mysql5.0 这个版本中时放在 mysql 安装目录 /data/ 下], 在 mysql5.5.19 下是需要查看
my.ini 的 datadir= C:/Documents and Settings/All Users/Application Data/MySQL/MySQL Server 5.5/Data/“
来确定.
 
Explain select * from emp where ename=“zrlcHd”会产生如下信息:
select_type: 表示查询的类型。
table: 输出结果集的表
type: 表示表的连接类型
possible_keys: 表示查询时,可能使用的索引
key: 表示实际使用的索引
key_len: 索引字段的长度
rows: 扫描的行数  www.2cto.com  
Extra: 执行情况的描述和说明
 
说起提高数据库性能,索引是最物美价廉的东西了。不用加内存,不用改程序,不用调 sql,只要执行个正确的 rsquo;create index rsquo;,
查询速度就可能提高百倍千倍,这可真有诱惑力。可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,
这些写操作,增加了大量的 I /O。 
是不是建立一个索引就能解决所有的问题?ename
上没有建立索引会怎样?
select * from emp where ename= lsquo;axJxC rsquo;;
 
索引的代价
磁盘占用
对 dml(update delete insert)语句的效率影响
** 四种索引的类型可以通过 myadmin 创建一个索引的时候看到
** 简述 mysql 四种索引的区别
PRIMARY 索引 =》在主键上自动创建
UNIQUE 索引 = 相当于 INDEX + Unique
INDEX 索引 = 就是普通索引
FULLTEXT = 只在 MYISAM 存储引擎支持, 目的是全文索引,在内容系统中用的多,在全英文网站用多(英文词独立). 中文数据不常用,意义不大 国内全文索引通常 使用 sphinx 来完成.
 
** 复合索引
create index 索引名 on 表名(列 1,列 2);
建立索引:create [UNIQUE|FULLTEXT]  index index_name on tbl_name (col_name [(length)] [ASC | DESC] , hellip;..); alter table table_name ADD INDEX [index_name] (index_col_name,…)
添加主键 (索引) ALTER TABLE 表名 ADD PRIMARY KEY(列名,..); 联合主键
删除索引 DROP INDEX index_name ON tbl_name; alter table table_name drop index index_name;  www.2cto.com  
删除主键 (索引) 比较特别: alter table t_b drop primary key;
查询索引 (均可) show index from table_name; show keys from table_name; desc table_Name;
下列的表将不使用索引:
1,如果条件中有 or,即使其中有条件带索引也不会使用。
2,对于多列索引,不是使用的第一部分,则不会使用索引。
3,like 查询是以 % 开头
4,如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。
5,如果 mysql 估计使用全表扫描要比使用索引快,则不使用索引。
 
添加一个主键索引
alter table dept add primary key (deptno)
– 测试语句
explain select * from dept where deptno=105\G;
结果是:
mysql explain select * from dept where deptno=105\G;
*************************** 1. row ***************************
           id: 1  www.2cto.com  
  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= lsquo;rjTUPqjZvf rsquo;\G; 会显示使用到了索引 myind
explain select * from dept where loc= lsquo;MsBDpMRX rsquo;\G; 不会显示使用到了索引 myind
– 对于使用 like 的查询
explain select * from dept where dname like lsquo;%rjTUPqjZvf rsquo;\G; 不会显示使用到了索引 myind
explain select * from dept where dname like lsquo;rjTUPqjZvf% rsquo;\G; 会显示使用到了索引 myind
– 如果条件中有 or,即使其中有条件带索引也不会使用
– 为了演示,我们把复合索引删除,然后只在 dname 上加入索引.
alter table dept drop index myind  www.2cto.com  
alter table dept add index myind (dname)
explain select * from dept where dname= lsquo;aaa rsquo; or loc= lsquo;aa rsquo;\G;// 就不会使用到 dname 列上的
– 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引
select * from dept from dname=1234\G // 不会使用到索引
select * from dept from dname= lsquo;1234 rsquo;\G // 会使用到索引
 
查看索引的使用情况 show status like lsquo;Handler_read% rsquo;; handler_read_key: 这个值越高越好,越高表示使用索引查询到的次数。
handler_read_rnd_next: 这个值越高,说明查询低效。
 
有些情况下,可以使用连接来替代子查询。因为使用 join,MySQL 不需要在内存中创建临时表。
如果想要在含有 or 的查询语句中利用索引,则 or 之间的每个条件列都必须用到索引,如果没有索引,则应该考虑增加索引
MyISAM 在插入数据时,默认放在最后., 删除数据后,空间不回收.(不支持事务和外键)
InnoDB 支持事务和外键
 
在精度要求高的应用中,建议使用定点数来存储数值,以保证结果的准确性
create table temp1(t1 float(10,2), t2 decimal(10,2));
insert into temp1 values(1000000.32,1000000,32); 发现 t1 成了 1000000.31 所以有问题.
对于存储引擎是 MyISAM 的, 如果经常做删除和修改记录的操作,要定时执行 optimize table table_name; 功能对表进行碎片整理。 
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 表结构文件.
 
如果一个表的记录数太多了, 如果我拆成 100 个表,那么每个表只有 10 万条记录。一个好的拆分依据是 最重要的。UNION 
有些表记录数并不多,可能也就 2、3 万条,但是字段却很长,表占用空间很大,检索表时需要执行大量 I /O,严重降低了性能。这个时候需要把大的字段拆分到另一个表,并且该表与原表是一对一的关系。(JOIN)

“mysql 语句的优化”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注丸趣 TV 网站,丸趣 TV 小编将为大家输出更多高质量的实用文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-01发表,共计4428字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)