【JAVA秒会技术之玩转SQL】MySQL优化技术(一)

MySQL优化技术(一)

        开发的路上,总会碰到一些老系统,越用越慢。“慢”的原因也许有很多,但是,博主个人觉得,数据库的设计和sql语句写的好坏,对系统效率的影响是最直接,最显而易见的!所以,学习一下MySQL的优化,还是很有必要的。当然,博主能力有限,没那么多经验,更多的是“道听途说”和“纸上谈兵”。如有不正之处,望大神开后给予指正,不胜感激!

(一)MySQL优化技术概述

表的设计合理化(符合3NF,即符合“三范式”。当然也要照顾“反范式”,要灵活);

添加适当索引(index)(主要包括:普通索引主键索引唯一索引unique全文索引);

SQL语句本身的优化(主要包括:避免全表扫描避免嵌套子查询等);

分表技术(水平分割垂直分割);

读写分离(其中写包括:update/delete/add);

存储过程模块化编程,可以提高速度,但是迁移性差,对服务器压力也会逐渐增大);

对mysql配置优化(主要是修改my.ini配置文件的参数信息)

mysql服务器硬件升级

定时的去清除不需要的数据,定时进行碎片整理(特别是使用了MyISAM)

(二)表的设计合理化

1.“三范式”(3NF)的概念

第一范式:1NF是对属性的原子性约束,要求属性(列)具有原子性,不可再分解;(只要是关系型数据库都满足1NF)

第二范式:2NF是在1NF满足的基础上,对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;

第三范式:3NF是在2NF满足的基础上,对字段冗余性的约束,要求字段没有冗余,也可以称为消除依赖传递

2.“反范式”(3NF)的概念

反范式:是通过增加冗余数据来提高数据库读性能的过程。

反范式出现的原因:当我们的业务所涉及的表非常多,经常会有多表联查,这样它的效率就会大打折扣,这时我们就可以考虑使用“反范式”。增加必要的,有效的冗余字段,用空间来换取时间,在查询时减少或者是避免过多表之间的联查。

3.举例

传智博客视频教程(业内良心,某宝2元钱买能一堆)中一个老项目为例,当时听得时候,觉得老师讲得神乎其神,列举其中的几个关键词,大家听听:三范式与反三范式分散计算思想打断设计添加冗余跳跃查询数据搬家等等。咋一听很能“蒙人”,后来博主画图总结了一下,其实,一说就破,很简单。

 

 

 

(三)Sql语句自身的优化

1.SHOW [ SESSION|GLOBAL ] STATUS指令的应用


#1.累计启动多少秒

SHOW STATUS LIKE 'uptime'

 

#2.累计查询/新增/修改/删除多少次

SHOW STATUS LIKE 'com_select'

SHOW STATUS LIKE 'com_insert'

SHOW STATUS LIKE 'com_update'

SHOW STATUS LIKE 'com_delete'

#注意:默认是SESSION当前会话级别的统计,全局的需要加上GLOBAL关键字

#默认的,当前会话级别的统计

SHOW SESSION STATUS LIKE 'com_select'

#全局的,统计从始至终

SHOW GLOBAL STATUS LIKE 'com_select'

 

#3.显示慢查询次数

SHOW GLOBAL STATUS LIKE 'slow_queries'

#显示当前慢查询时间,默认10秒

SHOW VARIABLES LIKE 'long_query_time'

#修改慢查询时间

SET long_query_time = 5

 

2.如何记录及定位慢查询

在默认情况下,我们的mysql不会记录慢查询,需要在启动mysql时候,指定记录慢查询才可以:


bin\mysqld.exe - -safe-mode  - -slow-query-log

[mysql5.5 以上可以在my.ini指定]

先关闭mysql,再启动, 如果启用了慢查询日志,默认把这个文件放在my.ini 文件中记录的位置:


#Path to the database root

datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"

查看慢查询日志:默认为数据目录data中的host-name-slow.log

(四)建立适当的索引

说起提高数据库性能,索引是最物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行个正确的‘create index’,查询速度就可能提高百倍千倍,这可真有诱惑力。可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的I/O。

索引主要分为:普通索引、主键索引、唯一索引、全文索引四大类,下面进行逐一说明:

1.索引添加

(1)主键索引添加

当一张表,把某个列设为主键的时候,则该列就是主键索引


create table aaa

(id int unsigned primary key auto_increment ,name varchar(32) not null defaul ‘’);

这时id 列就是主键索引。

如果你创建表时,没有指定主键索引,也可以在创建表后,再添加(不常用), 指令:


alter table 表名
add primary key (列名)

(2)普通索引

一般来说,普通索引的创建,是先创建表,然后再创建普通索引,比如:


create table 表名(

     id int unsigned,

     name varchar(32)

)create index索引名
on 表
(列1,列名2)
;

(3)创建全文索引

全文索引,主要是针对文件文本的检索, 比如文章,全文索引针对MyISAM有用

创建


CREATE TABLE articles (

       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,

       title VARCHAR(200),

       body TEXT,

       FULLTEXT (title,body)

     )engine=myisam charset utf8;

INSERT INTO articles (title,body) VALUES

     ('MySQL Tutorial','DBMS stands for DataBase ...'),

     ('How To Use MySQL Well','After you went through a ...'),

     ('Optimizing MySQL','In this tutorial we will show ...'),

     ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),

     ('MySQL vs. YourSQL','In the following database comparison ...'),

     ('MySQL Security','When configured properly, MySQL ...');

如何使用全文索引:


错误用法:

select * from articles where body like‘%mysql%’;【不会使用到全文索引】

证明:

explain
 select * from articles where body like ‘%mysql%’

正确的用法是:

select * from articles where match(title,body) against(‘database’);

*注意事项:

1.在mysql中fulltext 索引只针对MyISAM生效

2.mysql自己提供的fulltext针对英文生效->sphinx (coreseek) 技术处理中文

3.使用方法是 match(字段名..) against(‘关键字’)

4.全文索引一个叫停止词,  因为在一个文本中,创建索引是一个无穷大的数,因此,对一些常用词和字符,就不会创建,这些词,称为停止词。

(4)唯一索引

①当表的某列被指定为unique约束时,这列就是一个唯一索引。


create table ddd(id int primary key auto_increment , name varchar(32)unique);

这时, name 列就是一个唯一索引。

注意:unique字段可以为NULL,并可以有多NULL, 但是如果是具体内容,则不能重复

主键字段,不能为NULL,也不能重复。

②在创建表后,再去创建唯一索引。


create table eee(id int primary key auto_increment, name varchar(32));

create unique index 索引名  on表名
(列表..);

2.查询索引


desc 表名 【该方法的缺点是:不能够显示索引名.】

show index(es) from 表名\G

show keys from 表名\G

3.删除


alter table 表名 drop index 索引名;

如果删除主键索引。

alter table 表名 drop primary key       [这里有一个小问题]

4.修改

先删除,再重新创建.

5.索引的原理

(1)数据库的三层结构简图

 

(2)原始的查询图解

     

     原始的查询方法,查到number = 3后,仍然会往后查询,以为不确保后面是否有重复数据,所以是全表检索。至少要查询8次。

(2)对number建立索引后的查询图解

       

建立索引后,数据库会将索引字段,进行基于二叉树(B Tree / B+ Tree)的形式改造,并存储在“表名.MYI”的文件中。其后,再次查询时,只需查询2次即可,而且树节点记录的是物理地址,可以直接定位到元素,这样它的效率就大大的提高了。

6.索引的代价

①占用磁盘空间;

②对DML操作有影响,变慢;

7.何时创建索引

①较频繁的作为查询条件字段应该创建索引


select * from emp where empno = 1

②唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件


select * from emp where sex = ‘男’

③更新非常频繁的字段不适合创建索引


select * from emp where logincount = 1

④不会出现在WHERE子句中字段不该创建索

8.使用索引时的注意事项

创建如下复合索引:


    alter table dept add index my_ind (dname,loc);   # dname 左边的列,loc就是右边的列

如果我们的表中有复合索引(索引作用在多列上), 此时我们注意:

①对于创建的复合索引,只要查询条件使用了最左边的列,索引一般就会被使用


    explain select * from dept where loc= 'aaa'; #不会使用到索引

②对于使用like的查询,查询如果是‘%aaa’/‘_aaa’ 不会使用到索引,‘aaa%’/‘aaa_’ 会使用到索引


    explain select * from dept where dname like '%aaa'; #不会使用到索引

如果一定要前面有变化的值,则考虑使用全文索引->sphinx.

③如果条件中有or,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须建立索引, 我们建议大家尽量避免使用or 关键字


   select * from dept where dname=’xxx’ or loc=’xx’ or deptno=45; #不会使用到索引

④如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。(添加时,字符串必须’’), 也就是,如果列是字符串类型,就一定要用
‘’
把他包括起来。

⑤如果mysql估计使用全表扫描要比使用索引快,则不使用索引。

8.explain的应用

explain可以帮助我们在不真正执行某个sql语句时,就执行mysql怎样执行,这样利用我们去分析sql指令。

如何查看索引使用的情况:


   show status like ‘Handler_read%’;

注意:

handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。

handler_read_rnd_next:这个值越高,说明查询效率越低

时间: 2024-08-31 11:49:23

【JAVA秒会技术之玩转SQL】MySQL优化技术(一)的相关文章

【JAVA秒会技术之玩转SQL】MySQL优化技术(二)

MySQL优化技术(二) [前文连接]MySQL优化技术(一) (五)常用SQL优化 1.默认情况,在使用group by 分组查询时,会先分组,其后还会默认对组内其他条件进行默认的排序,可能会降低速度.这与在查询中指定order by col1, col2类似. 如果查询中包括group by但用户想要避免排序结果的消耗,则可以使用order by null禁止排序. 例子:   2.尽量使用左连接(或右连接)来替代普通多表联查.因为使用JOIN,MySQL不需要在内存中创建临时表.    s

SQL语句优化技术分析

优化|语句 操作符优化 IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格. 但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:        ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询.由此可见用IN的SQL至少多了一个转换的过程.一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不

ORACLE性能优化之SQL语句优化

文章来源:http://blog.csdn.net/jdzms23/article/details/23850783 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] SQL语句执行过程 1 SQL语句的执行步骤 2 典型SELECT语句完整的执行顺序 3 SQL语句执行过程 优化器及执行计划 1 SQL优化方法论 合理应用Hints 1Hints 索引及应用实例 1什么是索引 2索引分类 3什么时候使用索引 4改写SQL使用索引 5索引应用 其他优化技术及应用 1其他优化

Java编写一个图书管理系统,要使用JDVC技术访问,带有SQL数据库,请问怎么写

问题描述 Java编写一个图书管理系统,要使用JDVC技术访问,带有SQL数据库,请问怎么写 Java编写一个图书管理系统,要使用JDVC技术访问,带有SQL数据库,请问怎么写 解决方案 http://download.csdn.net/detail/u014029255/8284261 解决方案二: 1.写界面 2.写数据库连接 3.写数据库的增删改查 4.处理细节

JSP中SQL数据库编程技术

js|编程|数据|数据库   JSP中SQL数据库编程技术一,SQL复习 1,SQL语句分为两类:DDL(Data Definition Language)和DML(Dat Manipulation Languge,数据操作语言).前者主要是定义数据逻辑结构,包括定义表.视图和索引;DML主要是对数据库进行查询和更新操作. 2,Create Table(DDL):  Create Table tabName(   colName1 colType1 [else],   colName2 colT

四项技术 助你提高SQL Server的性能

本文讲解如何使用LEFT JOIN.CROSS JOIN以及IDENTITY值的检索,这些技术来提高基于SQL Server的应用程序的性能或改善其可伸缩性. 有时,为了让应用程序运行得更快,所做的全部工作就是在这里或那里做一些很小调整.但关键在于确定如何进行调整!迟早您会遇到这种情况:应用程序中的SQL 查询不能按照您想要的方式进行响应.它要么不返回数据,要么耗费的时间长得出奇.如果它降低了企业应用程序的速度,用户必须等待很长时间.用户希望应用程序响应迅速,他们的报告能够在瞬间之内返回分析数据

一次SQL语句优化的反思:技术和业务的脱节如何解决?

作者介绍 罗敏,从事Oracle技术研究.开发和服务工作20余年,在Oracle中国公司的10多年,分别在顾问咨询部.技术服务部担任资深技术顾问.曾参与国内银行.电信.政府等多个行业大型IT系统的建设和运维服务工作,为国内主要软件开发商和集成商进行过多场Oracle高级技术应用培训和交流活动.著有书籍<品悟性能优化>.<感悟Oracle核心技术>.<Oracle数据库技术服务案例精选>.   今天本人不妨对一条不太复杂的SQL语句在技术上进行深入剖析,与大家共同分享其中

聚簇索引与非聚簇索引的区别以及SQL Server查询优化技术

server|区别|索引|优化 在<数据库原理>里面,对聚簇索引的解释是:聚簇索引的顺序就是数据的物理存储顺序,而对非聚簇索引的解释是:索引顺序与数据物理排列顺序无关.正式因为如此,所以一个表最多只能有一个聚簇索引. 不过这个定义太抽象了.在SQL Server中,索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点.而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块.如下图: 非聚簇索引 聚簇索引 聚簇索引与非聚簇索引的本质区别到底是什么?

玩转SQL Server复制回路の变更数据类型、未分区表转为分区表

原文:玩转SQL Server复制回路の变更数据类型.未分区表转为分区表 玩转SQL Server复制回路の变更数据类型.未分区表转为分区表   复制的应用: 初级应用:读写分离.数据库备份 高级应用:搬迁大型数据库(跨机房).变更数据类型.未分区表转为分区表   京东的复制专家 菠萝 曾经写过文章.在数据库大会上也做过演讲,但是我相信真正按照菠萝兄的文章自己去做一次实验的人应该不多 京东的复制专家 菠萝 的文章地址:Replication的犄角旮旯(一)--变更订阅端表名的应用场景   为什麽