MySQL高级

MySQL高级

性能下降:1.查询语句写的烂 2.索引失效 3.关联查询太多join 4.服务器调优及参数设置(缓存,线程数等)

索引:

缺点:降低了更新表的速度,如对表进行insertupdatedelete,因为更新表时,mysql不仅要保存数据,还要保存索引文件每次跟新添加索引列的字段

索引分类:

单值索引 唯一(主键)索引(索引唯一,非空值) 复合索引

基本语法:

createuniqueindex indexName on tablecolumnnamelength));drop index indexNameon table;

 show index from table_name  

添加索引:alter TABLE table1_name add uniqueindex_namecolumn_list

索引结构:

适合建索引

1.主键自动建立唯一索引

2.频繁作为查询条件字段创建索引

3.查询中与其他表关联的字段,外键关系建立索引

4.频繁更新字段不适合建立索引

5.where条件用不到的字段不建立索引

6.查询中排序的字段,建立索引大大提高排序速度

7.查询中统计或者分组字段

不适合建索引

1.表记录少

2.经常增删改的表

3.某个数据包含了很多重复内容,为他建立索引没有太大的实际效果

性能优化:explain+sql语句

MySql常见瓶颈:

1.CPUcpu在饱和的时候一般发生在数据装入内存或者从磁盘读取数据时

2.IO:磁盘I/O 瓶颈发生在装入数据远大于内存容量的时候

3.服务器硬件性能瓶颈:top,free,iostat。。。查看系统性能状态

单表索引优化:

1.Where后面字段建索引

2.范围以后索引失效,解决方案:绕开范围查询建索引

两表索引优化:

1.左连接加右表

2.右连接建左表

三表索引优化:

1.小的结果集驱动大的结果集

2.优先优化嵌套里面的内层循环

3.保证join语句中被驱动表join条件字段已经被索引

索引失效原因

1.全值匹配我最爱(最佳左前缀法则)

2.最佳左前缀法则(查询从索引的最左前列开始并且不跳过索引中的列)简言之:带头大哥不能死

3.不在索引列上做任何操作(计算,函数,(自动or手动)类型转换),会导致索引失效而转向全表扫描

4.存储引擎不能使用索引中范围右边的列

5.尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *

6.使用不等于(!=或者<>)时候无法使用索引导致全表扫描

7.Is null,is not null也无法使用索引

8.Like以通配符(‘%abc....’mysql索引失效会变成全表扫描的操作,所以 like写右边,%aa%用覆盖索引(完全一致)解决问题

9.字符串不加单引号索引失效

10.少用or,用它来连接时索引会失效

实际SQL优化

①观察,至少跑一天,看生产的慢sql情况

②开启慢查询日志,设置阙值,并抓取

Explain+sql分析

Show profile

DBA进行sql数据库服务器参数调优

排序优化

1.小表驱动大表

Inexists

Select * from A where id inselect id from B(返回数据))

B表数据集必须小于A表的数据集时,用in优于exists

Select * from A where exists select 1 from B where B.id=A.id(返回truefalse))

A表的数据集小于B表的数据集时,用exists优于in

2.Order by 优化

两种情况会使用index方式排序:

order by 语句使用索引最左前列(order by a desc,b desc,c desc

②使用where字句与order by字句条件组合满足索引最左前列

③如果where使用索引的最左前缀定义为常量,则order by能使用索引 where a=const order by b,c

3.Group by 优化

group by实质是先排序后分组,遵循最左前缀

②无法使用索引时,增大参数设置

where高于having,能用where限定的不用having限定

存储过程

Delimiter $$

Create procedure insert_empin start int(10),in max_num int(10)

Begin

Declare i int default 0

Set autocommit=0;

Repeat

Set i=i+1;

Insert into emp(............);

Until i=max_num

End repeat;

Commit;

End $$;

调用存储过程

Call insert_dept(100,10) 100开始插入10

锁机制

操作类型:读锁,写锁,

粒度:行锁,表锁,页锁(了解)

手动添加表锁:lock table 表名 readwrite,表名2 read(write),其他

MyIsam--表锁

读锁(共享)

Session1

lock table mylock read

Update mylock set name=’a2’ where id=1;error

Select * from bookerror

Session2

Select * from mylock

Select * from book

Update mylock set name=’a3’ where id=1;(阻塞)

写锁(独占)

Session1

lock table mylock write

Select * from mylock

Update mylock set name=’a4’ where id=1;

Select * from book;(error

Session2

Select * from book;

Select * from mylock;(阻塞)

总结:读锁会阻塞写,不会阻塞读,写锁会把读和写都阻塞

Show open tables(查看哪些表被锁)

Innodb--行锁(5.5之后)

锁定某一行

Begin;

Select * from table where a=8 for update;

Commit;

Show status like ‘innodb_row_lock%’;

行锁优化建议

①尽可能让所有数据通过所有完成,避免无所有行锁升级为表锁

②合理设计索引,尽量缩小锁的范围

③尽可能较少检索条件,避免间隙锁

④尽量控制事物大小,减少锁定资源量和时间长度

⑤尽可能低级别事物隔离

 

 

 

 

 

 

 

 


你可能感兴趣的:(JavaWeb)