半年javaweb开发 性能很差 请各位老鸟拍砖 点评下 小弟先谢过了
补充一点 我觉得我这里慢的主要原因都是因为关联的太多 where后面的条件也多 我刚开始时条件不多 关联也不多 速度明显要快的多 这里有什么方法可以解决吗
public Paginate getBookInfoByPublishDateAndPublisher(Paginate paginate,
String unionSiteID,String publisher, Date fromDate, Date toDate, String bookName,
Double price1, Double price2, String vendor, String bookCategory) {
// TODO Auto-generated method stub
StringBuffer whereCause =new StringBuffer( "not exists(select l from UnionSiteProductList l where l.unionSiteID=? and b.bookID =l.productID)");
Vector paras = new Vector();
paras.add(unionSiteID);
if (publisher != null && publisher.trim().length() > 0) {
whereCause.append( (whereCause.length() > 0 ? " and " : "")
+ "b.publisherName like ?");
paras.add("%" + publisher + "%");
}
if (fromDate != null) {
whereCause.append( (whereCause.length() > 0 ? " and " : "")
+ "b.publishDate >= ?");
paras.add(fromDate);
}
if (toDate != null) {
whereCause.append( (whereCause.length() > 0 ? " and " : "")
+ "b.publishDate <= ?");
paras.add(toDate);
}
if (bookName != null && bookName.trim().length() > 0) {
whereCause.append((whereCause.length() > 0 ? " and " : "")
+ "b.bookName like ?");
paras.add("%" + bookName + "%");
}
if (price1 != null) {
whereCause.append( (whereCause.length() > 0 ? " and " : "")
+ "pp.productPrice >= ?");
paras.add(price1);
}
if (price2 != null) {
whereCause.append( (whereCause.length() > 0 ? " and " : "")
+ "pp.productPrice <= ?");
paras.add(price2);
}
if (vendor != null && vendor.trim().length() > 0) {
whereCause.append((whereCause.length() > 0 ? " and " : "")
+ "v.vendorName like ?");
paras.add("%" + vendor + "%");
}
if (bookCategory != null && bookCategory.trim().length() > 0) {
whereCause.append( (whereCause.length() > 0 ? " and " : "")
+ "bcv.bookCategoryName like ?");
paras.add("%" + bookCategory + "%");
}
String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";if (whereCause.length() > 0) { hql = hql + " and " + whereCause; } paginate = this.pagedQuery(hql, paginate, paras.toArray()); return paginate; }
String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
不需要改成 StringBulider或StringBuffer,因为这样累加,始终是一个String对象,例如:
String str1 = "hello " + "word" ;
String str2 ="hello word" ;
str1 = stru2
你的SQL,可以优化,like 不要前后都用 %,这样会全表扫描
判断是否为空,可以试试用 apache 的 StringUtils
方法参数太多,需要封装,提高可读性,你的代码严格的静态检查,肯定过不了
判断空的语句为什么不封装一下呢;每次都写不是很累;
放在一个ValidateUtil.isNull(String param) 里面多好;
我不知道你用的是什么框架还是纯的JDBC,如果用的是框架的话可以用其自带的分页,查询条件类似ibatis有动态SQL都可以用的;纯的去拼凑也是可以的。
不过都可以封装成一个方法; SQLUtil.addCause(String filed,String express) 这样代码复用稍微提高一点,美观一点;个人愚见,仅供参考
用ibatis吧,满足你的需求
whereCause.length()>0一直为true吧!
带十个参数的方法。。。NB。。
所谓的性能差是什么意思?
1.修改方法难
2.获取数据慢
String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
最好用StringBuffer代替,这种拼接也会影响效率
参数多了的话,我喜欢用HashMap
ibatis~你懂的。
StringBuffer改StringBuilder
Vector改ArrayList
没必要同步 个人意见
为什么不用MAP?
入参太多、整个方法相对太长,再封装多几个方法出来吧
第一你要分析出这段代码性能点在哪里然后找具体的方案去优化。
是查询数据库慢,还是什么慢?
[quote="败家小孩"] String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
最好用StringBuffer代替,这种拼接也会影响效率[/quote]
现在不会了在编译为CLASS的时候会把他转为StringBuilder
[quote="lyw985"]所谓的性能差是什么意思?
1.修改方法难
2.获取数据慢
[/quote]
同意:
你把所有条件都加上,组成一个sql 跑 看查询数据性能差吗/
还是你指的是 这样 并凑 sql 不好维护
carNum=#{carNum}
and drvName=#{drvName}
and baseNum=#{baseNum}
and beginDate BETWEEN #{beginDate} and #{endDate}
我只想知道,半年的你,现在多少米???
Jprofile看下性能 具体再调优下。
这主要就是sql的优化.如果你的功能要求就这么多参数,也没办法了.
保险起见,限定个最大结果数吧.
代码方面不必使用StringBuffer,Vector 都是局部变量.
你把sql打印出来去数据库查询下看需要多长时间。
如果时间很长的话分析出查询耗时在那里,然后做优化。
1,最简单的建索引,但这样插入会变慢,后期要修复索引。
2,改表结构,做数据冗余。
3,数据缓存
......等等
本人觉得连表查询不是最后的方法,尽量少用。当数据量大连表多的时候就会有性能问题了。
我想知道的是你用的什么数据库 数据量有多大 运行一条查询语句用了多长时间
[quote="败家小孩"] String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
最好用StringBuffer代替,这种拼接也会影响效率[/quote]
+1 我们在做项目的时候,一般都会使用拼接sql的形式来查询。
看来可能是数据库查询语句慢了,
楼主的代码还真是让人眼前一暗,这条HQL我愣是看半天,
建议:
把HQL生成输出一下,自己到数据测试运行
如果是SQL问题
将SQL贴出来,各表数据和关系贴出来,查询优化主要是SQL优化,
说实话,难以想象你这个方法是用什么思考方式写出来的,
如果是我,开发的时候,肯定先写完SQL测试过之后,才会写拼接的方法,
if (whereCause.length() > 0) {
hql = hql + " and " + whereCause;
}
这段代码有意义嘛?不是恒为真么?因为你一开始就初始化变量了。
paras.add("%" + bookCategory + "%");
这种是不走索引的,去掉开头的%可以走索引,但是前提是,
你所有的查询字段是按索引顺序排列的,
比如索引A,B,C 你必须是A LIKE a% and B like b%
不能是C like c%
and B like b%;
封装的很不好。。。。
[quote="yhz851225"][quote="败家小孩"] String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
最好用StringBuffer代替,这种拼接也会影响效率[/quote]
现在不会了在编译为CLASS的时候会把他转为StringBuilder[/quote]
有变量,5.0+ version的jvm会转成StringBuilder的。曾经的同事竟然非要用Stringbuffer,否则codereview不过。哎,可怜我的代码了,丑的不能再丑了。
感觉性能上,if的影响不大,查询条件影响太大了。修改查询条件吧
数据获取慢,看看是不是全表扫描,看看索引是不是没用上,跟踪sql执行过程看看
慢主要是数据库方面的知识,先看下她的执行计划。
你试着把一部分条件加到()里,我原来碰到过一次蛋疼的问题,整个查没什么,后来加了才几个条件就用了好几倍的时间觉得不正常,结果把查询的多个条件放进了()里就好了,我琢磨着不把查询条件放进括号是会对每条记录进行过滤,加了括号优先把前面的查询做完了,在从查询过的结果中进行过滤,也只能这么猜测了
你可以试着把容易过滤的条件放在前面
1:你的代码封装性是有待提高的,有些条件应该抽象出来。
2:你说你这些代码性能差,我建议你把你的SQL,单独抽离出来拿到数据库去执行一下。我想应该是表的索引使用的不好的原因。
3:string的拼接等操作,在这里是不会有明显的性能差别的,不过不是一个好习惯。
主要就是SQL的优化了
1.可以分拆SQL,按条件不同,用尽量少的表;
2.按查询条件的严格性从头到尾依次排放
3.合理用索引
直接写procedure.
兄弟的系统并发几何? 所谓性能差不一定是程序的问题吧.
为什么不使用String Builder然后用.append()方法连接字符串呢
[quote="za3999"]带十个参数的方法。。。NB。。[/quote]
是啊 佩服啊 十个参数。。。我还没写过超过四个参数的方法呢。。。看来是少见多怪了,唉!
[quote="败家小孩"] String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
最好用StringBuffer代替,这种拼接也会影响效率[/quote]
如果是JDK1.6以上的版本的话,这样写的效率比用StringBuffer更好,因为JAVA编译器会将它编译成一个字符串的字节码。
楼主可以看下《重构:改善既有代码的设计》 会对你有不少的帮助的
建索引,where条件从有索引到无索引顺序,从命中高到命中低顺序
[quote="fantasy"][quote="败家小孩"] String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
最好用StringBuffer代替,这种拼接也会影响效率[/quote]
如果是JDK1.6以上的版本的话,这样写的效率比用StringBuffer更好,因为JAVA编译器会将它编译成一个字符串的字节码。[/quote]
[code="java"]
public class StringTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
StringTest st = new StringTest();
st.StringTest_();
st.StringBufferTest_();
}
private void StringTest_(){
long start = System.currentTimeMillis();
String a = "你好:";
for(int i=0;i<10000;i++){
a=a+"xxx";
}
//System.out.println(a);
System.out.println("String时间差:"+(System.currentTimeMillis()-start));
}
private void StringBufferTest_(){
long start = System.currentTimeMillis();
StringBuffer a = new StringBuffer("你好:");
for(int i=0;i<10000;i++){
a.append("xxx");
}
//System.out.println(a);
System.out.println("StringBuffer时间差:"+(System.currentTimeMillis()-start));
}
}
[/code]
运行结果:
String时间差:384
StringBuffer时间差:2
我是在1.6下运行的!所以还是StringBuffer效率高!
[quote="败家小孩"] String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
最好用StringBuffer代替,这种拼接也会影响效率[/quote]
这种拼装跟StringBuffer的append效率貌似差不多,你说的那种情况应该是
String result = a + b + "123";(其中a,b都是String类型引用)
这种确实会印象效率,但是像上面那种情况,好像编译器会自动优化
:) 个人意见,仅供参考
[quote="p_3er"][quote="败家小孩"] String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
最好用StringBuffer代替,这种拼接也会影响效率[/quote]
+1 我们在做项目的时候,一般都会使用拼接sql的形式来查询。[/quote]
-1
己知不变常量用String快一些,中间有变量的才会用StringBuider快一些
[code="java"]
package com.service;
public class StringTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
StringTest st = new StringTest();
st.StringTest_();
st.StringBufferTest_();
}
private void StringTest_(){
long start = System.currentTimeMillis();
String a = "你好:";
for(int i=0;i<10000;i++){
[b]a="dd"+"xxx";[/b]
}
//System.out.println(a);
System.out.println("String时间差:"+(System.currentTimeMillis()-start));
}
private void StringBufferTest_(){
long start = System.currentTimeMillis();
StringBuffer a = new StringBuffer("你好:");
for(int i=0;i<10000;i++){
a.append("xxx");
}
//System.out.println(a);
System.out.println("StringBuffer时间差:"+(System.currentTimeMillis()-start));
}
}
[/code]
[b]String时间差:0
StringBuffer时间差:2[/b]
你这sql语句有些小的注意影响性能的地方太多
1.关联多的时候,可能把各表的这种数字条件放前面i.entityType=1这种关联条件b.bookID=i.entityID放后面
2.多条件下,数字条件在前,字符串条件在后
3.不要用过多的模糊查询,模糊查询用不上索引,会废了整个高效sql
4.精确条件放前面,模糊条件放后面
别小看放置顺序,看看数据库原理sql执行方面的你会懂的....
就说这么些
兄弟,你的LIKE用的太多了,还有用SQL 的 select a,b,c from A join B on
A.a=B.b 这种 2代SQL语法,这种语法性能强于1代SQL语法
[quote="thomaswen151"]兄弟,你的LIKE用的太多了,还有用SQL 的 select a,b,c from A join B on
A.a=B.b 这种 2代SQL语法,这种语法性能强于1代SQL语法[/quote]
支持!优化SQL非常重要!
多表连接查询 关联条件有没有写对 你那HQL查了6个表一不小心就会造成笛卡尔乘积 上面的一些逻辑判断影响不是很大 虽然你那做了一些没必要的操作 还有方法封装 慢主要是在查询慢 查的东西太多了
这代码看斗让人很蛋疼....
[quote="cectsky"][quote="yhz851225"][quote="败家小孩"] String hql = "select b,pp,v,bcv from Book b,ProductItem i,Product p, "
+ "ProductPrice pp,Vendor v,BookCategoryView bcv "
+ " where b.bookID=i.entityID and b.deleteFlag=0 and b.flag=4 "
+ " and i.entityType=1 and i.deleteFlag=0"
+ " and i.productID=p.productId and p.productType=1 and p.deleteFlag=0 and p.isValid=1"
+ " and p.productId=pp.productId and pp.deleteFlag=0"
+ " and b.vendorID = v.vendorID "
+ " and b.bookCategoryCode=bcv.bookCategoryCode ";
最好用StringBuffer代替,这种拼接也会影响效率[/quote]
现在不会了在编译为CLASS的时候会把他转为StringBuilder[/quote]
有变量,5.0+ version的jvm会转成StringBuilder的。曾经的同事竟然非要用Stringbuffer,否则codereview不过。哎,可怜我的代码了,丑的不能再丑了。
[/quote]
哈哈 我发现我也这样 不写成StringBuilder心理就不爽
从sql的角度来看,你都没考虑过利用索引来加快查询速度吗,如果数据量大,你这%%的全都用不上索引
[quote="抛出异常的爱"]select l from UnionSiteProductList l where l.unionSiteID=? and b.bookID =l.productID
这个子句去掉
在sql里加对应的联表与参数
还有就是看看page函数的写法总页数的生成方式可能有很大问题.[/quote]
主要是来看看抛哥
ps.女朋友也在成都
ibatis不错
UnionSiteProductList里的数据多吗? 你可以试试把这个去掉,会不会性能好一些(保证返回的数据差不多的情况做一下比较),我有一个数据库,和你有点类似,表里数据特别多,用not exists很慢。
先找出哪个地方优化空间比较大,再想办法优化。要不然无的放矢啊。如果对JProfile熟悉的话,这个是一个不错的选择,会帮你迅速确定是哪个方法慢。
1:尽量用分页
2:将SQL关监语句用大写
3:统一楼上,精确在前,模糊在后
4:用hibernate的话指定底层sql方言
5:尽量少创建java对象
6:StringBuffer与StringBuild的区别是,前者线程安全,但是慢,后者线程不安全,但是快!
7:查询对象的前后顺序也比较有讲究,这个得根据数据库原理来决定,左连接、右链接也是比较讲究的。(一言难尽)
8:尽量少创建中间对象,不过一些已经有的字符串变量会放到字符串对象池中
select l from UnionSiteProductList l where l.unionSiteID=? and b.bookID =l.productID
这个子句去掉
在sql里加对应的联表与参数
还有就是看看page函数的写法总页数的生成方式可能有很大问题.
可以讲sql语句做成配置文件
预编译,加载一次,没必要每次加载
为什么不把所有的查询条件封装成一个bean对象,这样代码也比较简单啊 ~!