MySQL数据库_索引_事务_优化 _锁_存储引擎_存储过程_CAP
##一、基础 ##
*    插入
 
                INSERT INTO table_name ( field1, field2,...fieldN )
                                       VALUES
                                       ( value1, value2,...valueN );
*    修改
              
                update tb set 字段1=值1,字段2=值2,。。 [where 条件]
* 删除
delete from tb [where 条件]
*    查询
          
                  select [distinct] 字段,字段 from tb   
                  [where 条件]   
                  [group by 字段]    
                  [having 条件]    
                  [order by 字段 desc/asc]    
                  [limit 0,5]
## order by 与 group by 以及 having 都是什么以及有哪些区别? ##
     order by  排序
group by 分组 必须有“聚合函数”来配合才能使用
where子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包 含聚组函数
having子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数
INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。        
     
     SELECT column_name(s)
      FROM table1
      INNER JOIN table2 ON table1.column_name = table2.column_name;
 
   LEFT JOIN(左连接):以左表作为基准进行查询,左表数据会全部显示出来,右表如果和左表匹配的数据则显示相应字段的数据,如果不匹配则显示为 null。                
     
      SELECT column_name(s)                
      FROM table1                
      LEFT JOIN table2                
      ON table1.column_name=table2.column_name;     
            
   RIGHT JOIN(右连接):以右表作为基准进行查询,右表数据会全部显示出来,左表如果和右表匹配的数据则显示相应字段的数据,如果不匹配则显示为 null。                                 
     
      SELECT column_name(s)                
      FROM table1                
      LEFT JOIN table2                
      ON table1.column_name=table2.column_name;
有一张表,如何找到指定字段重复的记录
select * from people where peopleId in ( select peopleId from people group by peopleId having count(peopleId) > 1 )
**数据库sql的优化**
1.保证不查询多余的列与行。
       2.慎用distinct关键字(去重)
       3.慎用union关键字(合并),满足union的语句必须满足:1.列数相同。 2.对应列数的数据类型要保持兼容
       4.判断表中是否存在数据?使用select count(1) id from product
       5.连接查询的优化,根据左右连接关联查询特点确定使用哪种查询方式
           select * from ((select * from orde where OrderId>10000) o  left join orderproduct op on o.orderNum=op.orderNum )
           select * from (orde o left join orderproduct op on o.orderNum=op.orderNum ) where o.OrderId>10000
       6.查询条件中,一定不要使用select *
       7.在表中建立索引,优先考虑where.group by使用到的字段
       8.对于连续的数值,能用 between 就不要用 in 
       9.尽量不要在 where 子句中对字段进行表达式操作
索引能够提高 SELECT 查询和 WHERE 子句的速度,但是却降低了包含 UPDATE 语句或 INSERT 语句的数据输入过程的速度。索引的创建与删除不会对表中的数据产生影响。创建索引需要使用 CREATE INDEX 语句,该语句允许对索引命名,指定要创建索引的表以及对哪些列进行索引,还可以指定索引按照升序或者降序排列。
MySQL数据库几个基本的索引类型:普通索引、唯一索引、主键索引、全文索引
普通索引:index
仅仅是加快查询速度
主键索引:primary key
不能重复,主键至多只有一个
唯一索引:unique index
行上的值不能重复
全文索引:fulltext index
CREATE INDEX index_name
        ON table_name (column_name);
索引可以用 SQL DROP 命令删除。删除索引时应当特别小心,数据库的性能可能会因此而降低或者提高。
DROP INDEX table_name.index_name;
## 哪些情况下需要设置索引、哪些情况下不需要 ##
需要:
1).主键自动建立唯一索引
2).频繁作为查询条件的字段应该创建索引
3).查询中与其它表关联的字段,外键关系建立索引
4).单键/组合索引的选择问题(在高并发下倾向创建组合索引)
5).查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
6).查询中统计或者分组字段
不需要:
1).表记录太少
2).经常增删改的表(因为不仅要保存数据,还要保存一下索引文件) 索引本来是一种事先在写的阶段形成一定的数据结构,从而使得在读的阶段效率较高的方式,但是如果一个字段是写多读少,则会降低写的速度。
3).数据重复且分布平均的表字段(比如性别),因此应该只为最经常查询和最经常排序的数据列建立索引。
4).where条件里用不到的字段不创建索引
## 建索引原则 ##
#1.选择唯一性索引
*
    唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名现象,从而降低查询速度。
#2.为经常需要排序、分组和联合操作的字段建立索引
*
    经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。
#3.为常作为查询条件的字段建立索引
*
    如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,为这样的字段建立索引,可以提高整个表的查询速度。
#4.限制索引的数目
*
    索引的数目不是越多越好。每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。
#5.尽量使用数据量少的索引
*
    如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索需要的时间肯定要比对CHAR(10)类型的字段需要的时间要多。
#6.尽量使用前缀来索引
*
    如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度。
#7.删除不再使用或者很少使用的索引
*
    表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。
#8 . 最左前缀匹配原则,非常重要的原则。
*
    mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a 1=”” and=”” b=”2” c=”“> 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
#9 .=和in可以乱序。
*
    比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
#10 . 尽量选择区分度高的列作为索引。
*
    区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就 是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条 记录
#11 .索引列不能参与计算,保持列“干净”。
*
    比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本 太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);
#12 .尽量的扩展索引,不要新建索引。 
*
    比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
#13、当单个索引字段查询数据很多,区分度都不是很大时,则需要考虑建立联合索引来提高查询效率
**  索引失效的场景:**
*
   like以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效。
*
   or语句前后没有同时使用索引。当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效。
*
   组合索引,不是使用第一列索引,索引失效。
*
   数据类型出现隐式转化。如varchar不加单引号的话可能会自动转换为int型,使索引无效,产生全表扫描。
*
   在索引列上使用 IS NULL 或 IS NOT NULL操作。索引是不索引空值的,所以这样的操作不能使用索引,可以用其他的办法处理,例如:数字类型,判断大于0,字符串类型设置一个默认值,判断是否等于默认值即可。
*
   在索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。 优化方法: key<>0 改为 key>0 or key<0。
*
   对索引字段进行计算操作。
*
   在索引字段上使用函数。
*
   当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效。
*
**索引失效分析工具:**
可以使用explain命令加在要分析的sql语句前面,在执行结果中查看key这一列的值,如果为NULL,说明没有使用索引。
**explain命令的详细用法**
https://segmentfault.com/a/1190000008131735
# 数据库优化 #
SQL以及索引的优化
数据库设计的优化
数据库三范式:
第一范式:数据表中每个字段都必须是不可拆分的最小单元,也就是确保每一列的原子性;
第二范式:满足一范式后,表中每一列必须有唯一性,都必须依赖于主键;
第三范式:满足二范式后,表中的每一列只与主键直接相关而不是间接相关(外键也是直接相关),字段没有冗余。
分表
分表方式
水平分割(按行)、垂直分割(按列)
分表场景
A: 根据经验,mysql表数据一般达到百万级别,查询效率就会很低。
B: 一张表的某些字段值比较大并且很少使用。可以将这些字段隔离成单独一张表,通过外键关联,例如考试成绩,我们通常关注分数,不关注考试详情。
水平分表策略
按时间分表:当数据有很强的实效性,例如微博的数据,可以按月分割。
按区间分表:例如用户表 1到一百万用一张表,一百万到两百万用一张表。
hash分表:通过一个原始目标id或者是名称按照一定的hash算法计算出数据存储的表名。
读写分离
当一台服务器不能满足需求时,采用读写分离【写: update/delete/add】的方式进行集群。
一台数据库支持最大连接数是有限的,如果用户的并发访问很多,一台服务器无法满足需求,可以集群处理。mysql集群处理技术最常用的就是读写分离。
主从同步:数据库最终会把数据持久化到磁盘,集群必须确保每个数据库服务器的数据是一致的。从库读主库写,从库从主库上同步数据。
读写分离:使用负载均衡实现,写操作都往主库上写,读操作往从服务器上读。
缓存
缓存分类
本地缓存:HashMap/ConcurrentHashMap、Ehcache、Guava Cache等
缓存服务:Redis/Tair/Memcache等
使用场景
短时间内相同数据重复查询多次且数据更新不频繁,这个时候可以选择先从缓存查询,查询不到再从数据库加载并回设到缓存的方式。此种场景较适合用单机缓存。
高并发查询热点数据,后端数据库不堪重负,可以用缓存来扛。
缓存作用
减轻数据库的压力,减少访问时间。
**MySQL锁**
## 行级锁 ##
行级锁是一种排他锁,防止其他事务修改此行;在使用以下语句时,Oracle 会自动应用行级锁:
1. INSERT、UPDATE、DELETE、SELECT … FOR UPDATE [OF columns] [WAIT n | NOWAIT];
2. SELECT … FOR UPDATE 语句允许用户一次锁定多条记录进行更新
3. 使用 COMMIT 或 ROLLBACK 语句释放锁。
## 表级锁 ##
表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分 MySQL 引擎支持。最常使
用的 MYISAM 与 INNODB 都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁
(排他锁)。
## 页级锁 ##
页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级
冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB 支持页级锁
## 基于 Redis 分布式锁 ##
1. 获取锁的时候,使用 setnx(SETNX key val:当且仅当 key 不存在时,set 一个 key
为 val 的字符串,返回 1;若 key 存在,则什么都不做,返回 0)加锁,锁的 value
值为一个随机生成的 UUID,在释放锁的时候进行判断。并使用 expire 命令为锁添
加一个超时时间,超过该时间则自动释放锁。
2. 获取锁的时候调用 setnx,如果返回 0,则该锁正在被别人使用,返回 1 则成功获取
锁。 还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
3. 释放锁的时候,通过 UUID 判断是不是该锁,若是该锁,则执行 delete 进行锁释放。
**MySQL事务**
**一.什么是事务?有什么用?事务的特性ACID **
事务提供了一种机制,可用来将一系列数据库更改归入一个逻辑操作。更改数据库后,所做的更改可以作为一个单元进行提交或取消。事务可确保遵循原子性、一致性、隔离性和持续性(ACID)这几种属性,以使数据能够正确地提交到数据库中。
      1)原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作 要么都发生,要么都不发生。     
      2)一致性(Consistency)一个事务中,事务前后数据的完整性必须保持一致。      
      3)隔离性(Isolation)多个事务,事务的隔离性是指多个用户并发访问数据库时, 一个用户的    事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。       
      4)持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变 就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
**二 事务的并发会产生的问题有哪些 **
## 1.脏读 ##
一个事务正在对数据进行更新操作,但是更新还未提交,另一个事务这时也来操作这组数据,并且读取了前一个事务还未提交的数据,而前一个事务如果操作失败进行了回滚,后一个事务读取的就是错误的数据,这样就造成了脏读
## 2.不可重复读 ##
一个事务多次读取同一个数据,在该事务还未结束时,另一个事务也对该数据进行了操作,而且在第一个事务两次读取之间,第二个事务对数据进行了更新,那么第一个事务前后两个读取到的数据是不同的,这样就造成了不可重复读
## 3.幻读 ##
第一个数据正在查询某一条数据,这时,另一个事务又插入了一条符合条件的数据,第一个事务在第二次查询符合同一条件的数据时,发现多了一条前一次查询时没有的数据,仿佛幻觉一样,这就是幻读
## 三 不可重复读和幻读的区别 ##
不可重复读是指在同一查询事务中多次进行,由于其他提交事务所做的修改和删除,每次返回不同的结果集,此时发生不可重复读。幻读是指在同一查询事务中多次进行,由于其他提交的事务所做的插入操作,每次返回不同的结果集,此时发生幻读表面上看,区别就在于不可重复读能看见其他事务提交的修改和删除,而幻读能看见其他事务提交的插入
**数据库并发策略**
并发控制一般采用三种方法,分别是乐观锁和悲观锁以及时间戳。
## 乐观锁 ##
乐观锁认为一个用户读数据的时候,别人不会去写自己所读的数据;悲观锁就刚好相反,觉得自
己读数据库的时候,别人可能刚好在写自己刚读的数据,其实就是持一种比较保守的态度;时间
戳就是不加锁,通过时间戳来控制并发出现的问题。
## 悲观锁 ##
悲观锁就是在读取数据的时候,为了不让别人修改自己读取的数据,就会先对自己读取的数据加
锁,只有自己把数据读完了,才允许别人修改那部分数据,或者反过来说,就是自己修改某条数
据的时候,不允许别人读取该数据,只有等自己的整个事务提交了,才释放自己加上的锁,才允
许其他用户访问那部分数据。
## 时间戳 ##
时间戳就是在数据库表中单独加一列时间戳,比如“TimeStamp”,每次读出来的时候,把该字
段也读出来,当写回去的时候,把该字段加1,提交之前 ,跟数据库的该字段比较一次,如果比数
据库的值大的话,就允许保存,否则不允许保存,这种处理方法虽然不使用数据库系统提供的锁
机制,但是这种方法可以大大提高数据库处理的并发量,
以上悲观锁所说的加“锁”,其实分为几种锁,分别是:排它锁(写锁)和共享锁(读锁)。
**CAP原则**
CAP原则又称CAP 定理,指的是在一个分布式系统中,Consistency(一致性)、Availability
(可用性)、Partition tolerance(分区容错性),三者不可得兼。
一致性(C):
1. 在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份
最新的数据副本)
可用性(A):
2. 在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备
高可用性)
分区容忍性(P):
3. 以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,
就意味着发生了分区的情况,必须就当前操作在 C 和 A 之间做出选择。
# MySQL存储引擎 #
# MySQL存储过程 #
MySQL数据库_索引_事务_优化 _锁_存储引擎_存储过程_CAP的更多相关文章
- MySQL数据库之索引、事务、存储引擎详细讲解
		一.索引 1.1 索引的概念 索引是一个排序的列表,存储着索引值和这个值所对应的物理地址 无须对整个表进行扫描,通过物理地址就可以找到所需数据 (数据库索引类似书中的目录,通过目录就可以快速査找所需信 ... 
- MySQL/MariaDB数据库的索引工作原理和优化
		MySQL/MariaDB数据库的索引工作原理和优化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 实际工作中索引这个技术是影响服务器性能一个非常重要的指标,因此我们得花时间去了 ... 
- 千万级MySQL数据库建立索引,提高性能的秘诀
		实践中如何优化MySQL 实践中,MySQL的优化主要涉及SQL语句及索引的优化.数据表结构的优化.系统配置的优化和硬件的优化四个方面,如下图所示: SQL语句及索引的优化 SQL语句的优化 SQL语 ... 
- MySQL数据库之索引
		1 引言 在没有索引的情况下,如果要寻找特定行,数据库可能要遍历整个数据库,使用索引后,数据库可以根据索引找出这一行,极大提高查询效率.本文是对MySQL数据库中索引使用的总结. 2 索引简介 索引是 ... 
- mysql如何查看索引使用情况以及优化 - guols0612
		mysql中支持hash和btree索引.innodb和myisam只支持btree索引,而memory和heap存储引擎可以支持hash和btree索引 我们可以通过下面语句查询当前索引使用情况: ... 
- MySQL数据库对象-索引
		1. 概述2. 索引分类2.1 不同索引的概念2.1.1 普通索引2.1.2 唯一索引2.1.3 全文索引2.1.4 多列索引3. 索引操作3.1 普通索引3.1.1 创建表时创建普通索引3.1.2 ... 
- MySQL性能调优与架构设计——第11章 常用存储引擎优化
		第11章 常用存储引擎优化 前言: MySQL 提供的非常丰富的存储引擎种类供大家选择,有多种选择固然是好事,但是需要我们理解掌握的知识也会增加很多.每一种存储引擎都有各自的特长,也都存在一定的短处. ... 
- Mysql数据库的触发器、存储引擎和存储过程
		数据库的触发器 1.触发器 触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句): DELETE,INSERT,UPDATE 我们可以监视某表 ... 
- Python--MySql(主键的创建方式、存储引擎、存储过程、索引、pymsql)
		主键的创建方式 1. create table stud( id int not null unique, name ) ); mysql> desc stud; +-------+------ ... 
随机推荐
- Mysql优化系列之查询性能优化前篇1
			前言 这是优化系列的最后一篇的第1小篇,我们其实可以直接从sql怎么写讲起,why not?但是我还是决定花2个篇幅 问一些问题,带着几个问题循序渐进的往下走. 一个sql语句是怎么被执行的? sql ... 
- 19.SimLogin_case04
			# 利用cookies登录马蜂窝 import requests from lxml import etree session = requests.Session() phone_number = ... 
- neo4j中cypher语句多个模糊查询
			总结一下经验: neo4j中,cypher语句的模糊查询,好像是个正则表达式结构. 对于一个属性的多个模糊查询,可以使用如下写法: 比如,查询N类型中,属性attr包含'a1'或者'a2'的所有节点. ... 
- wpf datepicker 样式
			在项目中用到的 <Style TargetType="{x:Type DatePicker}"> <Setter Property="Foregroun ... 
- 12-5-上下文this
			<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ... 
- 阻止a标签跳转/刷新
			<a href='javascript:;' onClick='functionA()'>点击</a> //注意":"."’":均需为英 ... 
- Hibernate的Hello World!
			一.创建Java工程,新建Lib文件夹,加入Hibernate和数据库(如MySql.Oracle.SqlServer等)的Jar包 二.创建 hibernate.cfg.xml 文件,并配置,配置项 ... 
- 2019-11-9-win10-支持默认把触摸提升-Pointer-消息
			title author date CreateTime categories win10 支持默认把触摸提升 Pointer 消息 lindexi 2019-11-09 15:32:31 +0800 ... 
- uboot 的移植过程
			1. 工作用户 uboot 2. uboot 版本 1.1.4 3. 工具链 2.95.3 步骤 我们为开发板取名叫: crane2410, 并在 uboot 中建立自己的开发板类型 修改 Mak ... 
- linux centos 恢复 还原 备份 Snapper 快照说明
			为什么要使用Snapper快照? 我们可以想像以下场景: 1. 场景一:系统发生意外宕机,工程师无法快速定位问题,业务受到中断,客户十分不满意. 2. 场景二:项目会议上,就是否升级某软件到最新版本, ... 
