zoukankan      html  css  js  c++  java
  • 数据库

    为什么用自增列作为主键

    如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引

    如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引

    如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。

    数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)

    如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页

    如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

    什么样的字段适合建索引

    唯一、不为空、经常被查询的字段

    哪些列适合建立索引、哪些不适合建索引?

    一般来说,应该在这些列上创建索引:

    (1)在经常需要搜索的列上,可以加快搜索的速度;

    (2)在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;

    (3)在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度

    (4)在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;

    (5)在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;

    (6)在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。

    对于有些列不应该创建索引:

    (1)对于那些在查询中很少使用或者参考的列不应该创建索引。

    这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。

    (2)对于那些只有很少数据值的列也不应该增加索引。

    这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。

    (3)对于那些定义为text, image和bit数据类型的列不应该增加索引。

    这是因为,这些列的数据量要么相当大,要么取值很少。

    (4)当修改性能远远大于检索性能时,不应该创建索引。

    这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。

    索引的好处与坏处

    1,好处:

      –帮助用户提高查询速度

      –利用索引的唯一性来控制记录的唯一性

      –可以加速表与表之间的连接

      –降低查询中分组和排序的时间 

    2,坏处

      –存储索引占用磁盘空间

      –执行数据修改操作(INSERT、UPDATE、DELETE)产生索引维护

    MySQL B+Tree索引和Hash索引的区别?

     Hash索引和B+树索引的特点:

      Hash索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位;

      B+树索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问;

     为什么不都用Hash索引而使用B+树索引?

    1. Hash索引仅仅能满足"=","IN"和""查询,不能使用范围查询,因为经过相应的Hash算法处理之后的Hash值的大小关系,并不能保证和Hash运算前完全一样;

    2. Hash索引无法被用来避免数据的排序操作,因为Hash值的大小关系并不一定和Hash运算前的键值完全一样;

    3. Hash索引不能利用部分索引键查询,对于组合索引,Hash索引在计算Hash值的时候是组合索引键合并后再一起计算Hash值,而不是单独计算Hash值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash索引也无法被利用;

    4. Hash索引在任何时候都不能避免表扫描,由于不同索引键存在相同Hash值,所以即使取满足某个Hash键值的数据的记录条数,也无法从Hash索引中直接完成查询,还是要回表查询数据;

    5. Hash索引遇到大量Hash值相等的情况后性能并不一定就会比B+树索引高。

    6.  B+树可以部分放入内存查询,而Hash表必须一次读入内存,相对消耗内存空间比较大。

    补充:

    1.MySQL中,只有HEAP/MEMORY引擎才显示支持Hash索引。

    2.常用的InnoDB引擎中默认使用的是B+树索引,它会实时监控表上索引的使用情况,如果认为建立哈希索引可以提高查询效率,则自动在内存中的“自适应哈希索引缓冲区”建立哈希索引(在InnoDB中默认开启自适应哈希索引),通过观察搜索模式,MySQL会利用index key的前缀建立哈希索引,如果一个表几乎大部分都在缓冲池中,那么建立一个哈希索引能够加快等值查询。

    B+树索引和哈希索引的明显区别是:

    3.如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值;当然了,这个前提是,键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到相应的数据;

    4.如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索;

    同理,哈希索引没办法利用索引完成排序,以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);

    5.哈希索引也不支持多列联合索引的最左匹配规则;

    6.B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题。

    7.在大多数场景下,都会有范围查询、排序、分组等查询特征,用B+树索引就可以了。

    count(*)、count(1)、count(column)的区别

    • count(*)对行的数目进行计算,包含NULL

    • count(column)对特定的列的值具有的行数进行计算,不包含NULL值。

    • count()还有一种使用方式,count(1)这个用法和count(*)的结果是一样的。

    性能问题:

    1.任何情况下SELECT COUNT(*) FROM tablename是最优选择;

    2.尽量减少SELECT COUNT(*) FROM tablename WHERE COL = ‘value’ 这种查询;

    3.杜绝SELECT COUNT(COL) FROM tablename WHERE COL2 = ‘value’ 的出现。

    • 如果表没有主键,那么count(1)比count(*)快。

    • 如果有主键,那么count(主键,联合主键)比count(*)快。

    • 如果表只有一个字段,count(*)最快。

    count(1)跟count(主键)一样,只扫描主键。count(*)跟count(非主键)一样,扫描整个表。明显前者更快一些。

    B树和B+树的区别

    1. B+树中只有叶子节点会带有指向记录的指针(ROWID),而B树则所有节点都带有,在内部节点出现的索引项不会再出现在叶子节点中。

    2. B+树中所有叶子节点都是通过指针连接在一起,而B树不会。

    3. 叶子节点之间通过指针来连接,范围扫描将十分简单,而对于B树来说,则需要在叶子节点和内部节点不停的往返移动。

    索引为什么使用B+树而不使用红黑树

    为什么不是B-树?

    如何衡量查询效率呢?– 磁盘IO次数。
    一般来说索引非常大,尤其是关系性数据库这种数据量大的索引能达到亿级别,所以为了减少内存的占用,索引也会被存储在磁盘上。B-树/B+树 的特点就是每层节点数目非常多,层数很少,目的就是为了减少磁盘IO次数,但是B-树的每个节点都有data域(指针),这无疑增大了节点大小,说白了增加了磁盘IO次数磁盘IO一次读出的数据量大小是固定的,单个数据变大,每次读出的就少,IO次数增多,一次IO多耗时),而B+树除了叶子节点其它节点并不存储数据,节点小,磁盘IO次数就少。
    优点一: B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域。
    优点二: B+树所有的Data域在叶子节点,并且所有叶子节点之间都有一个链指针。 这样遍历叶子节点就能获得全部数据,这样就能进行区间访问啦。在数据库中基于范围的查询是非常频繁的,而B树不支持这样的遍历操作。

    为什么不是红黑树?

    B树是多路树,红黑树是二叉树!红黑树一个节点只能存出一个值,B树一个节点可以存储多个值,红黑树的深度会更大,定位时 红黑树的查找次数会大一些。

    AVL 数和红黑树基本都是存储在内存中才会使用的数据结构。在大规模数据存储的时候,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况。为什么会出现这样的情况,我们知道要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写。磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读写。根据磁盘查找存取的次数往往由树的高度所决定,所以,只要我们通过某种较好的树结构减少树的结构尽量减少树的高度,B树可以有多个子女,从几十到上千,可以降低树的高度。

    数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。

    聚集索引和非聚集索引区别

    聚合索引(clustered index):

    聚集索引表记录的排列顺序和索引的排列顺序一致,所以查询效率快,只要找到第一个索引值记录,其余就连续性的记录在物理也一样连续存放。聚集索引对应的缺点就是修改慢,因为为了保证表中记录的物理和索引顺序一致,在记录插入的时候,会对数据页重新排序。

    非聚合索引(nonclustered index):

    非聚集索引指定了表中记录的逻辑顺序,但是记录的物理和索引不一定一致,两种索引都采用B+树结构,非聚集索引的叶子层并不和实际数据页相重叠,而采用叶子层包含一个指向表中的记录在数据页中的指针方式。非聚集索引层次多,不会造成数据重排。

    举例:如果在一棵高度为3的辅助索引中查找数据,那么需要对这棵辅助索引树遍历3词找到指定主键,如果聚集索引树的高度同样是3,那么还需要对聚集索引进行3次查找,最终找到一个完整的行数据所在的页,因此一共需要6次逻辑IO访问得到最终的一个页的数据。

    覆盖索引

    从辅助索引中就可以得到查询的记录,而不需要查询聚集索引中的记录。使用覆盖索引的好吃是辅助索引不饱含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作。

    我们常常说select的时候最好不要 select * ,而要写成select col1,col2....这种形式,但是如果在不使用覆盖索引的情况下, select * 和select col1,col2....的区别不大,select * 只不过多返回了一些字段,增加了一点网络传输上的消耗罢了,其实可以忽略不计。但是如果使用到了覆盖索引,那么他们之间的执行时间差距就大了。select col1 from table; select * from table;如果col1是一个辅助索引,那么Mysql只需要查询这个辅助索引就够了,而select * from table除了要查询辅助索引以外,还要再查一次聚集索引,这就就造成了额外的性能开销。数据量大的情况下,这两种查询的执行时间可能会相差十几倍。

    哈希索引

    全文索引

    事务的并发?事务隔离级别,每个级别会引发什么问题,MySQL默认是哪个级别?

     从理论上来说, 事务应该彼此完全隔离, 以避免并发事务所导致的问题,然而, 那样会对性能产生极大的影响, 因为事务必须按顺序运行, 在实际开发中, 为了提升性能, 事务会以较低的隔离级别运行, 事务的隔离级别可以通过隔离事务属性指定。

    事务的隔离级别及其并发问题

     读未提交:会出现脏读。另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据脏读

    已提交读:不可重复读。事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果因此本事务先后两次读到的数据结果会不一致。

    可重复读:在同一个事务里,SELECT的结果是事务开始时时间点的状态,因此,同样的SELECT操作读到的结果会是一致的。但是,会有幻读现象

    幻读举例,事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作 这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。 而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有跟没有修改一样,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

    串行化:最高的隔离级别,在这个隔离级别下,不会产生任何异常。并发的事务,就像事务是在一个个按照顺序执行一样。

    MySQL中默认事务隔离级别是“可重复读”时并不会锁住读取到的行

    事务隔离级别:未提交读时,写数据只会锁住相应的行。

    事务隔离级别为:可重复读时,写数据会锁住整张表。

    事务隔离级别为:串行化时,读写数据都会锁住整张表。

    隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大,鱼和熊掌不可兼得啊。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

    mysql事务是怎么实现的?

    mysql的默认的隔离级别是RR,并且在RR的隔离级别下更进一步,通过多版本并发控制(MVCC)解决不可重复读问题,加上间隙锁(也就是并发控制)解决幻读问题。因此innoDB的RR隔离级别其实实现了串行化级别的效果,而且保留了比较好的并发性能。事务的隔离性是通过实现,而事务的原子性、一致性和持久性则是通过事务日志实现。其实就是redo和undo日志。

    redo log

    在innoDB的存储引擎中,事务日志通过 重做(redo)日志 日志缓冲(InnoDB Log Buffer) 实现。

    事务开启时,事务中的操作,都会先写入日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是所谓的的“日志先行”。

    当事务提交之后,在Buffer Pool中映射的数据文件才会慢慢刷新到磁盘。此时如果数据库崩溃或者宕机,那么当系统重启进行恢复时,就可以根据redo log中记录的日志,把数据库恢复到崩溃前的一个状态。未完成的事务,可以继续提交,也可以选择回滚,这基于恢复的策略而定。

    undo log

    undo log主要为事务的回滚服务。在事务执行的过程中,除了记录redo log,还会记录一定量的undo log。undo log记录了数据在每个操作前的状态,如果事务执行过程中需要回滚,就可以根据undo log进行回滚操作。单个事务的回滚,只会回滚当前事务做的操作,并不会影响到其他的事务做的操作。

    • 以下是undo+redo事务的简化过程:

      假设有2个数值,分别为A和B,值为1,2

        1. start transaction;
        2. 记录 A=1 undo log;
        3. update A = 34. 记录 A=3 redo log5. 记录 B=2 undo log6. update B = 47. 记录B = 4 redo log8. redo log刷新到磁盘
        9. commit

    在1-8的任意一步系统宕机,事务未提交,该事务就不会对磁盘上的数据做任何影响。如果在8-9之间宕机,恢复之后可以选择回滚,也可以选择继续完成事务提交,因为此时redo log已经持久化。若在9之后系统宕机,内存映射中变更的数据还来不及刷回磁盘,那么系统恢复之后,可以根据redo log把数据刷回磁盘。

    所以,redo log其实保障的是事务的持久性和一致性,而undo log则保障了事务的原子性。

    分布式事务

    MySQL的分布式事务模型分三块:应用程序(AP)、资源管理器(RM)、事务管理器(TM)

    • 应用程序定义了事务的边界,指定需要做哪些事务;
    • 资源管理器提供了访问事务的方法,通常一个数据库就是一个资源管理器;
    • 事务管理器协调参与了全局事务中的各个事务。

    分布式事务采用两段式提交(two-phase commit)的方式。

    • 第一阶段所有的事务节点开始准备,告诉事务管理器ready。
    • 第二阶段事务管理器告诉每个节点是commit还是rollback。

    如果有一个节点失败,就需要全局的节点全部rollback,以此保障事务的原子性。

    事务传播行为

    1.PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

    2.PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

    3.PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

    4.PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

    5.PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

    6.PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

    7.PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

    嵌套事务

    什么是嵌套事务?

    嵌套是子事务套在父事务中执行,子事务是父事务的一部分,在进入子事务之前,父事务建立一个回滚点,叫save point,然后执行子事务,这个子事务的执行也算是父事务的一部分,然后子事务执行结束,父事务继续执行。重点就在于那个save point。看几个问题就明了了:

    如果子事务回滚,会发生什么?

    父事务会回滚到进入子事务前建立的save point,然后尝试其他的事务或者其他的业务逻辑,父事务之前的操作不会受到影响,更不会自动回滚。

    如果父事务回滚,会发生什么?

    父事务回滚,子事务也会跟着回滚!为什么呢,因为父事务结束之前,子事务是不会提交的,我们说子事务是父事务的一部分,正是这个道理。那么:

    事务的提交,是什么情况?

    是父事务先提交,然后子事务提交,还是子事务先提交,父事务再提交?答案是第二种情况,还是那句话,子事务是父事务的一部分,由父事务统一提交。

    MySQL常见的三种存储引擎(InnoDB、MyISAM、MEMORY)的区别?

    1,InnoDB支持事务,外键,MyISAM不支持。

    2,InnoDB中不保存表的行数,如select count() from table时,InnoDB需要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count()语句包含where条件时MyISAM也需要扫描整个表。

    3,对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引。

    4,DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的 删除,效率非常慢。MyISAM则会重建表。

    5,InnoDB支持行锁

    6,InnoDB不支持FULLTEXT类型的索引。5.6版本以后开始支持。

    mysql都有什么锁

    表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

    行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

    页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

    mysql的行级锁是怎么实现的?

    在mysql中,有Lock和Latch的概念,在数据库中,这两者都可以被称为“锁”

    Latch一般称为闩锁(轻量级的锁),因为其要求锁定的时间必须非常短。若持续的时间长,则应用的性能会非常差,在InnoDB引擎中,Latch又可以分为mutex(互斥量)和rwlock(读写锁)。其目的是用来保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。

    Lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行。并且一般lock的对象仅在事务commit或rollback后进行释放(不同事务隔离级别释放的时间可能不同)。

    这里只介绍Lock

    对数据的操作其实只有两种,也就是读和写,而数据库在实现锁时,也会对这两种操作使用不同的锁;InnoDB 实现了标准的行级锁,也就是共享锁(Shared Lock)和互斥锁(Exclusive Lock)。

    • 共享锁(读锁),允许事务读一行数据。
    • 排他锁(写锁),允许事务删除或更新一行数据。

    待补充

    一致性非锁定读

    待补充

    多版本控制协议(MVCC)

    待补充

    有哪些锁(乐观锁悲观锁),select 时怎么加排它锁?

    悲观锁:先获取锁,再进行业务操作。需要数据库提供支持

    通过常用的select … for update操作来实现悲观锁。当数据库执行select for update时会获取被select中的数据行的行锁,因此其他并发执行的select for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。

    MySQL还有个问题是select for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题。因此如果在MySQL中用悲观锁务必要确定走了索引,而不是全表扫描。

    乐观锁 在数据库上的实现完全是逻辑的,不需要数据库提供特殊的支持。

    多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,那么当前正在提交的事务会进行回滚。

    一般的做法是在需要锁的数据上增加一个版本号,或者时间戳

    乐观锁在不发生取锁失败的情况下开销比悲观锁小,但是一旦发生失败回滚开销则比较大,因此适合用在取锁失败概率比较小的场景,可以提升系统并发性能

    乐观锁还适用于一些比较特殊的场景,例如在业务操作过程中无法和数据库保持连接等悲观锁无法适用的地方。

    因此:

    响应速度: 如果需要非常高的响应速度,建议采用乐观锁方案,成功就执行,不成功就失败,不需要等待其他并发去释放锁。'

    冲突频率: 如果冲突频率非常高,建议采用悲观锁,保证成功率,如果冲突频率大,乐观锁会需要多次重试才能成功,代价比较大。

    重试代价: 如果重试代价大,建议采用悲观锁。

    慢查询

    1,分析慢查询日志

      直接分析mysql慢查询日志 ,利用explain关键字可以模拟优化器执行SQL查询语句,来分析sql慢查询语句

    2,常见的慢查询优化

      ① 索引没起作用的情况

        1) 使用LIKE关键字的查询语句,2) 使用多列索引的查询语句。具体索引失效的情况看下面。

      ② 优化数据库结构

        1)将字段很多的表分解成多个表

          对于字段比较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。

        2)增加中间表

          对于需要经常联合查询的表,可以建立中间表以提高查询效率。通过建立中间表,把需要经常联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询,以此来提高查询效率。

      ③ 分解关联查询

        将一个大的查询分解为多个小查询是很有必要的。

        很多高性能的应用都会对关联查询进行分解,就是可以对每一个表进行一次单表查询,然后将查询结果在应用程序中进行关联,很多场景下这样会更高效。

      ④ 优化LIMIT分页

        1)虑筛选字段(title)上加索引

        2)先查询出主键id值

        3)关延迟联

          比如:Select news.id, news.description from news inner join (select id from news order by title limit 50000,5) as myNew using(id);

          这里的“关延迟联”将大大提升查询的效率,它让MySQL扫描尽可能少的页面,获取需要的记录后再根据关联列回原表查询需要的所有列。这个技术也可以用在优化关联查询中的limit。

        4)建立复合索引

      ⑤ 分析具体的sql

        1)两个表选哪个为驱动表,表面是可以以数据量的大小作为依据,但是实际经验最好交给mysql查询优化器自己去判断。

      摘自https://blog.csdn.net/qq_35571554/article/details/82800463  

    5种常见的异常

    NullPointerException,ClassNotFoundException,ArithmeticException(数学运算异常),ArrayIndexOutOfBoundsException ,IllegalAccessException(没有访问权限)

    ClassNotFoundException,IllegalArgumentException(方法传递参数错误)

    MySQL索引失效的几种情况

    1,如果条件中有or,即使其中有条件带索引也不会使用

    2,like查询以%开头

    3,对于多列索引,不是使用的第一部分,则不会使用索引

    4,如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引

    5,如果mysql估计使用全表扫描要比使用索引快,则不使用索引 (键值较少的列 重复数据较多的列)

    6,查询时,采用is null条件时,不能利用到索引,只能全表扫描。

    Redis种阻塞的命令

    BLPOP key [key ...] timeout

    Redis的数据结构

    String,hash,list,set,zset

    Redis快的主要原因

    1,完全基于内存

    2,数据结构简单,对数据操作也简单

    3,使用多路 I/O 复用模型

    4,避免了不必要的上下文切换,和资源的竞争等待。

    Redis单线线程的缺点

    无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善

  • 相关阅读:
    WCF学习笔记1发布使用配置文件的服务
    Oracle(Hierarchical Queries)层级查询
    Telerik UI For WinForms关于RadGridView的列排序
    C#异步显示工作进度
    CodeSmith连接Oracle
    Access数据导入SQLServer2008R2
    Oracle (RANK) 排名函数
    C#INotifyPropertyChanged(解决数据绑定的界面刷新问题)
    Code Complete读书笔记03
    C++ Primer Plus读书笔记08
  • 原文地址:https://www.cnblogs.com/xueyunqing/p/11017687.html
Copyright © 2011-2022 走看看