Sql优化:
1. 查询语句不使用Select *
2. 少使用子查询 用关联查询(left join right join left join) 代替
3. or查询时尽量使用uniun union all 数据不重复或不需要剔除重复数据情况下 uniun all 比uniun 更好
4. 尽量避免在where子句使用<> 或者!= 操作符,否则导致引擎放弃索引而进行全表扫描
5. 不要在where子句中对字段使用nul判断, 多用0 where 条件= 0
6. 减少使用not in 或not 用exists 或not exists 或关联语句代替
Drop truncate delete
Truncate Delete 删除表数据
Drop 删除表结构
Truncate drop ddl 操作立即生效,原数据放不到rollback segements 中,不能回滚,操作不触发trigger
Delete dml 操作会放在rollback,segements中,事务提交后才生效,如果有相应的trigger,执行的时候会被触发
速度:drop > truncate >delete
Rollback segements
视图
视图是虚拟表,具有和物理表相同的功能,可以进行增删改等一系列操作,视图通常是有一个表或多个表的行或列的子集,对视图的操作不影响物理表,相比多表查询更容易使我们获取数据。
并发事务带来哪些问题?
脏读
不可重复读:一个事务内多次读同一数据,这个事务还未结束,另一个事务也访问这条数据,在第一个事务两次读数据之间,由于第二个事务的修改导致读数据的两次不同,就出现了一个事务两次读数据的不同,因此称不可重复读
丢失修改:第一个事务读取数据并做了修改,另一个事务也读取事务并做修改,那么第一个事务访问的就是第二个事务的数据,那么第一事务修改的数据就丢失了
幻读:一个事务读取了几行数据,另一个事务插入了几行数据,在之后的查询中,就会多了一些原本不存在的记录,
不可重复读和幻读区别:
不可重复读是修改,比如多次读取一条记录发现某些列的值被修改,
幻读的重点是新增或删除,比如多次读取一条记录发现记录增多或减少了
事务隔离级别?mysql的默认隔离级别?
读取已提交:允许读取并发事务已提交的数据,可阻止脏读,但是幻读和不可重复读仍有可能发生
读取未提交:允许读取尚未提交的数据变更,可能导致脏读 幻读 不可重复读,最低的隔离级别
可重复读:同一字段读取结果一致,除非数据是被本身事务所修改,可以阻止脏读和不可重复读,但是幻读仍有可能发生
可串行化:最高的隔离级别,完全服从ACID的隔离级别,所有事务依次逐个执行,这样事务之间互补干扰,可以防止脏读,幻读不可重复读
Mysql InnoDB存储引擎默认的隔离级别是可重复读
大表如何优化
限定数据的范围:务必禁止不带任何限制数据范围条件的查询语句
读写分离:主库负责写 从库负责读
垂直分区:数据表列的拆分,把一张列较多的表拆分多张表,如图
优点:使数据列变小,查询时减少读取的Block数(BLOCK是数据库中的最小存储和处理单位,包含块本身的头信息数据或PL/SQL代码),减少I/O(Input output system 输入输出系统)次数,简化表结构,易于维护
缺点 : 主键会出现冗余,需要管理冗余列,会引起join操作,可通过在应用层进行join解决,垂直分区会让事务变得复杂
水平分区
保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达到了分布式的目的。 水平拆分可以支撑非常大的数据量。
水平拆分是指数据表行的拆分,表的行数超过200万行时,就会变慢,这时可以把一张的表的数据拆成多张表来存放。
举个例子:将用户信息表拆分成多个用户信息表,可避免单一表数据量过大对性能造成影响。
水平拆分可以支持非常大的数据量。
需要注意的一点是:分表仅仅是解决了单一表数据过大的问题,但由于表的数据还是在同一台机器上,其实对于提升MySQL并发能力没有什么意义,所以 水平拆分最好分库
水平拆分优点:支持非常大的数据量存储,应用端改造也少,
水平拆分缺点: 分片事务难以解决 ,跨节点Join性能较差,逻辑复杂。
《Java工程师修炼之道》的作者推荐 尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度 ,一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。如果实在要分片,尽量选择客户端分片架构,这样可以减少一次和中间件的网络I/O。
分库分表后,id主键如何处理
需生成全局ID,有以下几种方式生成全局ID
uuid:不适合做主键,因过长,无序不可读,查询效率低,适合生成唯一的名字标示比如文件名
数据库自增ID:两台数据分别设置不同步长,生成不重复id的策略实现高可用,优点:id有序,缺点:需要独立部署数据库实例,成本高,有性能瓶颈
利用redis生成id:性能较好,灵活方便,不依赖数据库,但是引入新的组件造成系统复杂,可用性降低,编码复杂,增加系统成本。
扩展:
美团的Leaf分布式ID生成系统 :Leaf 是美团开源的分布式ID生成器,能保证全局唯一性、趋势递增、
单调递增、信息安全,里面也提到了几种分布式方案的对比,但也需要依赖关系数据库、Zookeeper等
中间件。感觉还不错
存储过程(特定功能的SQL语句集)
一组为了完成特定功能的SQL语句集,存储在数据库中,经过第一个编译再次调用不需再次编译,用户通过指定存储过程名字并给出指定参数(如有带参数)来执行,存储过程是数据库的一个重要对象。
存储过程优化思路
1.尽量使用一些SQL语句代替一些小循环,例如聚合函数,求平均函数等。
2.中间结果存放于临时表,加索引。
3.少使用游标,sql是个集合语言,对集合运算具有较高性能,而cursors是过程运算,
举例:查询一万条数据,游标需要查询一万次,而不使用游标只需少量几次读取。
4.事务越短越好。sqlserver支持并发操作,如事务过长过多,隔离级别过高,都会造成并发操作的阻塞,死锁,导致查询效率低,cpu占用率极低。
5.查询语句不要放循环内
6.使用try-catch 处理错误异常
触发器(一段能自动执行的程序)
触发器是一段能自动执行的程序,是一种特殊的存储过程,触发器和普通存储过程的区别:触发器是当对某张表进行操作时触发,比如:update delete insert ,系统会自动调用执行该表上对应的触发器。
SQL Server2005后,触发器分为DML 和DDL,其中DDL会影响多种数据定义语言语句而激发,这些语句有:create drop alter 等。
数据库并发策略
并发控制采用悲观锁 乐观锁 时间戳三种方式
MYSQL有哪几种锁
1.表级锁:开销小,加锁快,不会出现死锁,锁定粒度大,发生锁冲突的概率最高,并发度最低
2.行级锁:开销大,加锁慢,会出现死锁,锁定粒度最小,发生锁冲突的概率最低,并发度最高
3.页面锁:开销和加锁时间介于表锁和行锁之间,会出现死锁,锁定粒度介于表锁和行锁之间,并发度一般。
MYSQL有哪些不同的表格
MyISAM
Heap
Merge
INNODB
ISAM