1. 数据库设计要合理
2. 添加索引(普通索引、朱建索引、唯一索引、全文索引)
3. 分表分库技术(取模分表、水平分表、垂直分表)
4. 读写分离
5. 存储过程
6. 配置mysql最大连接数my.ini
7. mysql服务器升级
8. 随时清理碎片化
9. sql语句调优
create table user0(
id int unsigned primary key ,
name varchar(32) not null default '',
pwd varchar(32) not null default '')
engine=myisam charset utf8;
create table user1(
id int unsigned primary key ,
name varchar(32) not null default '',
pwd varchar(32) not null default '')
engine=myisam charset utf8;
create table user2(
id int unsigned primary key ,
name varchar(32) not null default '',
pwd varchar(32) not null default '')
engine=myisam charset utf8;
create table uuid(
id int unsigned primary key auto_increment)engine=myisam charset utf8;
创建一个demo项目
POM文件
org.springframework.boot
spring-boot-starter-parent
1.3.3.RELEASE
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-web
Service代码
@Service
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public String regit(String name, String pwd) {
// 1.先获取到 自定增长ID
String idInsertSQL = "INSERT INTO uuid VALUES (NULL);";
jdbcTemplate.update(idInsertSQL);
Long insertId = jdbcTemplate.queryForObject("select
last_insert_id()", Long.class);
// 2.判断存储表名称
String tableName = "user" + insertId % 3;
// 3.注册数据
String insertUserSql = "INSERT INTO " + tableName + " VALUES ('"
+ insertId + "','" + name + "','" + pwd
+ "');";
System.out.println("insertUserSql:" + insertUserSql);
jdbcTemplate.update(insertUserSql);
return "success";
}
public String get(Long id) {
String tableName = "user" + id % 3;
String sql = "select name from " + tableName + " where id="+id;
System.out.println("SQL:" + sql);
String name = jdbcTemplate.queryForObject(sql, String.class);
return name;
}
}
Controller
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/regit")
public String regit(String name, String pwd) {
return userService.regit(name, pwd);
}
@RequestMapping("/get")
public String get(Long id) {
String name = userService.get(id);
return name;
}
}
配置文件
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
如何从一个大项目中,迅速的定位执行速度慢的语句. (定位慢查询)
使用show status使用show status查看MySQL服务器状态信息
常用命
--mysql数据库启动了多少时间
show status like 'uptime';
show stauts like 'com_select' show stauts like 'com_insert' ...
类推 update delete(显示数据库的查询,更新,添加,删除的次数)
show [session|global] status like .... 如果你不写 [session|global] 默认是
session 会话,指取出当前窗口的执行,如果你想看所有(从mysql 启动到现在,则应该
global)
//显示到mysql数据库的连接数
show status like 'connections ';
//显示慢查询次数
show status like 'slow_queries';
什么是慢查询
MySQL默认10秒内没有响应SQL结果,则为慢查询
可以去修改MySQL慢查询默认时间
--查询慢查询时间
show variables like 'long_query_time';
--修改慢查询时间
set long_query_time=1; ---但是重启mysql之后,long_query_time依然是my.ini中的值
创建表结构
/*部门表*/
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 ;
/*员工表*/
CREATE TABLE emp
(empno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*编号*/
ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/
job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/
mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上级编号*/
hiredate DATE NOT NULL,/*入职时间*/
sal DECIMAL(7,2) NOT NULL,/*薪水*/
comm DECIMAL(7,2) NOT NULL,/*红利*/
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部门编号*/
)ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
/*薪水*/
CREATE TABLE salgrade
(
grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
losal DECIMAL(17,2) NOT NULL,
hisal DECIMAL(17,2) NOT NULL
)ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*测试数据*/
INSERT INTO salgrade VALUES (1,700,1200);
INSERT INTO salgrade VALUES (2,1201,1400);
INSERT INTO salgrade VALUES (3,1401,2000);
INSERT INTO salgrade VALUES (4,2001,3000);
INSERT INTO salgrade VALUES (5,3001,9999);
创建函数
create function rand_string(n INT)
returns varchar(255) #该函数会返回一个字符串
begin
#chars_str定义一个变量 chars_str,类型是 varchar(100),默认
值'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
declare chars_str varchar(100) default
'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
declare return_str varchar(255) default '';
declare i int default 0;
while i < n do
set return_str =concat(return_str,substring(chars_str,floor(1+rand()*52),1));
set i = i + 1;
end while;
return return_str;
end
create FUNCTION rand_num()
RETURNS int(5)
BEGIN
DECLARE i int default 0;
set i =floor(10+RAND()*500);
return i;
delimiter $$
create procedure insert_emp(in start int(10),in max_num int(10))
begin
declare i int default 0;
#set autocommit =0 把autocommit设置成0
set autocommit = 0;
repeat
set i = i + 1;
insert into emp values ((start+i)
,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());
until i = max_num
end repeat;
commit;
end $$
执行存储过程
call insert_emp (100001,40000000);
在默认情况下,我们的mysql不会记录慢查询,需要在启动mysql时候,指定记录慢查询才可
以
bin\mysqld.exe --safe-mode --slow-query-log [mysql5.5 可以在my.ini指定](安全模
式启动,数据库将操作写入日志,以备恢复)
bin\mysqld.exe –log-slow-queries=d:/abc.log [低版本mysql5.0可以在my.ini指定]
先关闭mysql,再启动, 如果启用了慢查询日志,默认把这个文件放在
my.ini 文件中记录的位置
#Path to the database root
datadir=" C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式
保存
索引
为什么要索引?-----提高查询效率,为什么加了索幻能够提高查询效
率…索引实现原理折半查找
索引分类:
主键索引—primary key
唯一索引
组合索引
全文索引
普通索引
1.不要like
企业实际中不会采用表的全文索引
全文索引缺点:
第三方搜索索引框架slor、es等
索引优缺点:
优点:提高程序效率
缺点:增加、删除慢,索引文件需要更新、增加内存
什么字段适合加索引?
select * from user where sex=*S’;—不需要
查询次数比较,值有非常多的不同。
select * from user where userid=112;—需要
建立索引where条件需要查询的,并且值非常多的不
同。唯一几个值,不需要建立索引
第一个可以不用第二一起作为条件查找…会使用组索引进行查
找
第二个条件,不使用第一个条件----不会使用组合索幻查找
使用第一个条件和第二条件一起查找使用索引进行
创建表结构
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%'; 错误用法 索引不会生效
正确用法:
select * from articles where match(title,body) against ( 'database')
说明:
create table ddd(id int primary key auto_increment , name varchar(32) unique);
注意
create table ccc(
id int unsigned,
name varchar(32)
)
create index 索引名 on 表 (列1,列名2);
查询作为查询条件字段应该创建索引
唯一性太差的字段不适合单独创建索引,即使频繁
Select * from emp where sex=’男’
频繁更新字段,也不要定义索引。
不会出现在where语句的字段不要创建索引
总结:满处一下条件的字段,才应该创建索引
1. 肯定在where条件经常使用
2. 该字段的内容不是唯一的几个值
3. 字段内容不是频繁变化
注意:
1.对于创建的多列索引,如果不是使用第一部分,则不会创建索引。
explain select * from dept where loc=‘aaa’\G
就不会使用到索引
2.模糊查询在like前面有百分号开头会失效。
3. 如果条件中有or,即使其中有条件带索引也不会使用。换言之,就是要求使
用的所有字段,都必须建立索引, 我们建议大家尽量避免使用or 关键字
4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使
用索引。(添加时,字符串必须’’), 也就是,如果列是字符串类型,就一定要用
‘’ 把他包括起来.
5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引。