zoukankan      html  css  js  c++  java
  • j2EE开发之代码优化心得

    1、建立索引为什么能加快查询速度:  

    这是因为,创建索引可以大大提高系统的性能。

    第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性

    第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。

    第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特

          别有意义。

    第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分

          组和排序的时间。

    第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的

         性能。
         索引的缺点:

    第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 

    第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要

         占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。

    第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,

         这样就降低了数据的维护速度

     

    2、需要建立索引的地方:

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

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

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

    ④在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的

      范围是连续的;

    ⑤在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引

      的排序,加快排序查询时间;

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


    3、不需要建立索引的情况:

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

    第二,对于那些只有很少数据值的列也不应该增加索引。如性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。

    第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。

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


    4、触发器和存储过程的优缺点汇总

    缺点:

    ①可移植性是存储过程和触发器最大的缺点。

    ②占用服务器端太多的资源,对服务器造成很大的压力

    ③不能做DDL。

    ④触发器排错困难,而且数据容易造成不一致,后期维护不方便。

    优点:①预编译,已优化,效率较高。避免了SQL语句在网络传输然后再解释

         的低效率。

    ②存储过程可以重复使用,减少开发人员的工作量。

    ③业务逻辑封装性好,修改方便。

    ④安全。不会有SQL语句注入问题存在。

    5、怎样能提高程序运行速度

    ①提高编程技术水平,优化代码,比如使用某些特殊的数据结构或算法,这样可

      以提高代码的运行效率,才不会导致限制的时间不够用;

    ②避免随意使用静态变量:当某个对象被定义为stataic变量所引用,那么gc通

      常是不会回收这个对象所占有的内存;

    ③避免过多过常的创建java对象,避免在经常调用的方法,循环中new对象,

      由于系统不仅要花费时间来创建对象,而且还要花时间对这些对象进行垃圾回 

      收和处理,在我们可以控制的范围内,最大限度的重用对象,最好能用基本的

      数据类型或数组来替代对象;

    ④尽量使用final修饰符,使用局部变量,使用StringBuilder和StringBuffer进行

      字符串连接,使用基本数据类型代替对象;

    ⑤单线程应尽量使用HashMap, ArrayList HashTable,Vector等使用了同步机

      制,降低了性能。

    ⑥尽量避免使用二维数组,二维数据占用的内存空间比一维数组多得多,大概

      10倍以上。

    6hibernate常用的接口和类

    ① Configuration 接口:配置Hibernate,根据其启动hibernate,创建SessionFactory 对

       象;

    ② SessionFactory 接口:初始化Hibernate,充当数据存储源的代理,创建session 对象,

       sessionFactory 是线程安全的,意味着它的同一个实例可以被应

       用的多个线程共享,是重量级、二级缓存;

    ③ Session 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,

       避免多个线程共享同一个session,是轻量级、一级缓存;

    ④ Transaction 接口:管理事务;

    ⑤ Query 和Criteria 接口:执行数据库的查询。

    7Hibernate工作原理及为什么要用?

    原理:

    1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件

    2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析

      映射信息

    3.通过config.buildSessionFactory();//创建SessionFactory

    4.sessionFactory.openSession();//打开Sesssion

    5.session.beginTransaction();//创建事务Transation

    6.persistent operate持久化操作

    7.session.getTransaction().commit();//提交事务

    8.关闭Session

    9.关闭SesstionFactory

    为什么要用Hibernate

    1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码;

    2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度

      的简化DAO层的编码工作;

    3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。

    4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关

      系数据库,从一对一到多对多的各种复杂关系。

    Hibernate优缺点

    1. Hibernate优点

    (1) 对象/关系数据库映射(ORM)  它使用时只需要操纵对象,使开发更对象化,抛弃了数据库中心的思想,完全的面向对象思想。

    (2) 透明持久化(persistent)  带有持久化状态的、具有业务功能的单线程对象,此对象生存期很短。这些对象可能是普通的JavaBeans/POJO,这个对象没有实现第三方框架或者接口,唯一特殊的是他们正与(仅仅一个)Session相关联。一旦这个Session被关闭,这些对象就会脱离持久化状态,这样就可被应用程序的任何层自由使用。(例如,用作跟表示层打交道的数据传输对象。)           

    (3) 事务Transaction(org.hibernate.Transaction)  应用程序用来指定原子操作单元范围的对象,它是单线程的,生命周期很短。它通过抽象将应用从底层具体的JDBC、JTA以及CORBA事务隔离开。某些情况下,一个Session之内可能包含多个Transaction对象。尽管是否使用该对象是可选的,但无论是使用底层的API还是使用Transaction对象,事务边界的开启与关闭是必不可少的。

    (4) 它没有侵入性,即所谓的轻量级框架;

    (5) 移植性会很好;

    (6) 缓存机制,提供一级缓存和二级缓存;

    (7) 简洁的HQL编程;

    2. Hibernate缺点

    (1)  Hibernate在批量数据处理时有弱势;

    (2)  针对单一对象简单的增删查改,适合于Hibernate,而对于批量的修改,删除,不适合用Hibernate,这也是ORM框架的弱点;要使用数据库的特定优化机制的时候,不适合用Hibernate。

    Hibernate是如何延迟加载?

        在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载

    延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。即,当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。

    Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)

    类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many。

     hibernate基本的缓存机制

    第一级存放于session中称为一级缓存,属于应用事物级缓存只缓存实体,生命周期和session一致。默认带有且不能卸载。

    第二级是由sessionFactory控制的进程级缓存,使用第3方插件实现的,生命周期和sessionFactory一致,可以进行管理。查询时使用缓存的实现过程为:首先查询一级缓存中是否具有需要的数据,如果没有,查询二级缓存。

    只有经正确的配置后二级缓存才会发挥作用。同时在进行条件查询时必须使用相应的方法才能从缓存中获取数据。比如Query.iterate()方法、load、get方法等。必须注意的是session.find方法永远是从数据库中获取数据,不会从二级缓存中获取数据,即便其中有其所需要的数据也是如此。

    如何优化Hibernate?

    1.使用双向一对多关联,不使用单向一对多;

    2.灵活使用单向一对多关联;

    3.不用一对一,用多对一取代;

    4.配置对象缓存,不使用集合缓存;

    5.一对多集合使用Bag,多对多集合使用Set;

    6. 继承类使用显式多态;

    7. 表字段要少,表关联不要怕多,有二级缓存撑腰。

    8、如何优化SQL 

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上

      建立索引。

    2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而

     进行全表扫描,如:select id from t where num is null 可以在num上设置默认值0,确保

     表中num列没有null值,然后这样查询:

      select id from t where num=0

    3.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全

      表扫描。

    4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行

      全表扫描,如:select id from t where num=10 or num=20

    可以这样查询:

    select id from t where num=10

    union all

    select id from t where num=20

    5.in 和 not in 也要慎用,否则会导致全表扫描,如:

    select id from t where num in(1,2,3)

    对于连续的数值,能用 between 就不要用 in 了:

    select id from t where num between 1 and 3

    6.下面的查询也将导致全表扫描:

    select id from t where name like "%abc%";  若要提高效率,可以考虑全文检索。

    7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:

    select id from t where num=@num

    可以改为强制查询使用索引:

    select id from t with(index(索引名)) where num=@num

    8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:

    select id from t where num/2=100

    应改为:

    select id from t where num=100*2

    9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

    select id from t where substring(name,1,3)="abc"--name以abc开头的id

    select id from t where datediff(day,createdate,"2005-11-30")=0--‘2005-11-30’生成的id

    应改为:

    select id from t where name like "abc%"

    select id from t where createdate>="2005-11-30" and createdate<"2005-12-1"

    10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

    11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

    12.不要写一些没有意义的查询,如需要生成一个空表结构:

    select col1,col2 into #t from t where 1=0

    这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:

    create table #t(...)

    13.很多时候用 exists 代替 in 是一个好的选择:

    select num from a where num in(select num from b)

    用下面的语句替换:

    select num from a where exists(select 1 from b where num=a.num)

    14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

    15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

    16.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

    17.任何地方都不要使用 select * from t ,用具体的字段列表代替“ * ,不要返回用不到的任何字段。

    18.避免频繁创建和删除临时表,以减少系统表资源的消耗。

    19.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

    20.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

    21.尽量避免大事务操作,提高系统并发能力。

    22.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

    ===========仅供参考==========

  • 相关阅读:
    数据科学面试应关注的6个要点
    Python3.9的7个特性
    一种超参数优化技术-Hyperopt
    梯度下降算法在机器学习中的工作原理
    MQ(消息队列)功能介绍
    D. The Number of Pairs 数学
    F. Triangular Paths 思维
    D. XOR-gun 思维和 + 前缀
    C. Basic Diplomacy 思维
    D. Playlist 思维
  • 原文地址:https://www.cnblogs.com/xm1-ybtk/p/5099079.html
Copyright © 2011-2022 走看看