论坛首页 综合技术论坛

低效的where 1=1

浏览 41502 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2010-07-13  
ywlqi 写道
Das_flamen 写道
superyang 写道
抛出异常的爱 写道
 
StringBuffer buffer = new StringBuffer("select * from T where 1=1 ");
for(Map.Enty e : map){
    buffer .appand ("and "+ e.getKey()+" = '"+e.getValue()+"'");
}




		String hql = "select e.id,e.name,e.provice,e.city,e.total,date_format(e.addtime,'%Y-%m-%d'),a.name,date_format(e.sendtime,'%Y-%m-%d') from email e,admin a where e.add_admin_id=a.id";

		if (!this.isNull(email_type)) {

			hql += " and e.name like '%" + email_type + "%'";
		}
		if (!this.isNull(provice)) {

			hql += " and e.provice like '%" + provice + "%'";
		}
		if (!this.isNull(city)) {

			hql += " and e.city like '%" + city + "%'";
		}
		if (!this.isNull(name)) {

			hql += " and e.name like '%" + name + "%'";
		}
		if (!this.isNull(add_admin_id)) {

			hql += " and e.adminByAddAdminId.id='" + add_admin_id + "'";
		}
		if (!this.isNull(order_type)) {

			String arr[] = order_type.split("_");
			hql += " order by e." + arr[0] + " " + arr[1];
			hql += ",e.addtime desc";
		} else {
			hql += " e.addtime desc";
		}
	
		



这样写可不可以??
为什么很多人用StringBuffer的..???

你可以去试下,StringBuffer的效率不是String能比的,拼接的时候String多了严重影响性能。当然,如果就几条那也没什么,不过强烈推荐不要用String,不是个好习惯。


我记得有帖子说过jdk1.5以后对字符串相加做了优化,效率和StringBuffer一样了啊,我没做过实验,谁做过实验的来说两句

在编译的时候,确实会适时的将字符串拼接转成StringBuilder
0 请登录后投票
   发表时间:2010-07-13  
qchong 写道
ywlqi 写道
Das_flamen 写道
superyang 写道
抛出异常的爱 写道
 
StringBuffer buffer = new StringBuffer("select * from T where 1=1 ");
for(Map.Enty e : map){
    buffer .appand ("and "+ e.getKey()+" = '"+e.getValue()+"'");
}




		String hql = "select e.id,e.name,e.provice,e.city,e.total,date_format(e.addtime,'%Y-%m-%d'),a.name,date_format(e.sendtime,'%Y-%m-%d') from email e,admin a where e.add_admin_id=a.id";

		if (!this.isNull(email_type)) {

			hql += " and e.name like '%" + email_type + "%'";
		}
		if (!this.isNull(provice)) {

			hql += " and e.provice like '%" + provice + "%'";
		}
		if (!this.isNull(city)) {

			hql += " and e.city like '%" + city + "%'";
		}
		if (!this.isNull(name)) {

			hql += " and e.name like '%" + name + "%'";
		}
		if (!this.isNull(add_admin_id)) {

			hql += " and e.adminByAddAdminId.id='" + add_admin_id + "'";
		}
		if (!this.isNull(order_type)) {

			String arr[] = order_type.split("_");
			hql += " order by e." + arr[0] + " " + arr[1];
			hql += ",e.addtime desc";
		} else {
			hql += " e.addtime desc";
		}
	
		



这样写可不可以??
为什么很多人用StringBuffer的..???

你可以去试下,StringBuffer的效率不是String能比的,拼接的时候String多了严重影响性能。当然,如果就几条那也没什么,不过强烈推荐不要用String,不是个好习惯。


我记得有帖子说过jdk1.5以后对字符串相加做了优化,效率和StringBuffer一样了啊,我没做过实验,谁做过实验的来说两句

在编译的时候,确实会适时的将字符串拼接转成StringBuilder

别信任何jvm作出的承诺
比如线程优先级
比如某string池的优化
比如string可以自己用buffer解析
0 请登录后投票
   发表时间:2010-07-13  
where 1=1看起来很笨,很别扭,见过很多人这样写,本人很是反感
0 请登录后投票
   发表时间:2010-07-13   最后修改:2010-07-13
sundoctor 写道
where 1=1看起来很笨,很别扭,见过很多人这样写,本人很是反感

本质上是为了节约二个if而已.
StringBuffer buffer = new StringBuffer("select * from T ");

if (!haveNoPara(map)){
  boolean isFirst = true;
  for(Map.Enty e : map){
      if(isFirst){
          buffer.appand(" where ");
          isFirst = false;
      }else{     
          buffer .appand(" and ");
      }
     buffer .appand ( e.getKey()+" = '"+e.getValue()+"'");
  }
}

 
StringBuffer buffer = new StringBuffer("select * from T where 1=1 ");
for(Map.Enty e : map){
    buffer .appand ("and "+ e.getKey()+" = '"+e.getValue()+"'");
}
0 请登录后投票
   发表时间:2010-07-13  
stefanoli_0705 写道
pi1ot 写道
我怎么从来没遇到过需要这么用的时候,举个例子


我们公司在应用ibatis查询的时候,很多这么写,确实比较省事


用ibatis完全可以用其他的方法实现。就像官方文档写的:

MyBatis 有个简单的方案就能解决这里面90%的问题。如果where 没有出现的时候,你可以自定一个。
稍稍修改一下,就能完全解决:
<select id=”findActiveBlogLike”
parameterType=”Blog” resultType=”Blog”>
SELECT * FROM BLOG
<where>
<if test=”state != null”>
state = #{state}
</if>
<if test=”title != null”>
AND title like #{title}
</if>
<if test=”author != null and author.name != null”>
AND title like #{author.name}
</if>
</where>
</select>

这个“where”元素会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签
返回的内容是以AND 或OR 开头的,则它会剔除掉。
如果where 元素并没有完全按你想要的那样,那你也可以使用trim 元素自定义它。下面的trim 也相同于
where:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
…
</trim>
0 请登录后投票
   发表时间:2010-07-13  
maozj 写道
即便用到索引 也不会用到其优化性


都全表扫描了,还什么索引啊。
0 请登录后投票
   发表时间:2010-07-13  
superyang 写道
maozj 写道
superyang 写道
好像是很低效,一个邮件收集系统才10万多条数据就已经变得很慢了,也查不出是什原因..(mysql5.0)


以前是这样的hql:
select e.id,e.name,date_format(e.addtime,'%Y-%m-%d'),e.admin.name,date_format(e.sendtime,'%Y-%m-%d') from email e where 1=1;

现在改为这样native-sql:
select e.id,e.name,date_format(e.addtime,'%Y-%m-%d'),a.name,date_format(e.sendtime,'%Y-%m-%d') from email e,admin a where e.add_admin_id=a.id
也是很慢.


---

select count(e.id) from email e where 1=1







查询到数据量为5万多,点分页就快一点.
查询全部数据量,点分页就相当慢.

很欣慰你的细腻



能分析一下是什么问题?
能解决吗?

赏分:100分...




加索引了没有,数据量不是很大啊
0 请登录后投票
   发表时间:2010-07-13  
ywlqi 写道
Das_flamen 写道
superyang 写道
抛出异常的爱 写道
 
StringBuffer buffer = new StringBuffer("select * from T where 1=1 ");
for(Map.Enty e : map){
    buffer .appand ("and "+ e.getKey()+" = '"+e.getValue()+"'");
}




		String hql = "select e.id,e.name,e.provice,e.city,e.total,date_format(e.addtime,'%Y-%m-%d'),a.name,date_format(e.sendtime,'%Y-%m-%d') from email e,admin a where e.add_admin_id=a.id";

		if (!this.isNull(email_type)) {

			hql += " and e.name like '%" + email_type + "%'";
		}
		if (!this.isNull(provice)) {

			hql += " and e.provice like '%" + provice + "%'";
		}
		if (!this.isNull(city)) {

			hql += " and e.city like '%" + city + "%'";
		}
		if (!this.isNull(name)) {

			hql += " and e.name like '%" + name + "%'";
		}
		if (!this.isNull(add_admin_id)) {

			hql += " and e.adminByAddAdminId.id='" + add_admin_id + "'";
		}
		if (!this.isNull(order_type)) {

			String arr[] = order_type.split("_");
			hql += " order by e." + arr[0] + " " + arr[1];
			hql += ",e.addtime desc";
		} else {
			hql += " e.addtime desc";
		}
	
		



这样写可不可以??
为什么很多人用StringBuffer的..???

你可以去试下,StringBuffer的效率不是String能比的,拼接的时候String多了严重影响性能。当然,如果就几条那也没什么,不过强烈推荐不要用String,不是个好习惯。


我记得有帖子说过jdk1.5以后对字符串相加做了优化,效率和StringBuffer一样了啊,我没做过实验,谁做过实验的来说两句


一个是线程安全的,一个不是现成的,你说那个快。。。
0 请登录后投票
   发表时间:2010-07-13  
stefanoli_0705 写道
pi1ot 写道
我怎么从来没遇到过需要这么用的时候,举个例子


我们公司在应用ibatis查询的时候,很多这么写,确实比较省事


ibatis也会用到这种写法??
我觉得ibatis最方便的地方就是动态组合各种查询条件

select * from Table
<dynamic prepend="where">
    <isNotNull .... prepend="and">...</isNotNull>
    .....
</dynamic>


就算isNotNull条件成立,也不会出现where and语句,ibatis已经处理好了
0 请登录后投票
   发表时间:2010-07-13  
老天呀,培训机构害死人呀,不教好的,只教坏的. 加1=1 就是为了在没有指定查询条件时查询语句不出错.你们真的是懒到家了.这与数据库真的一点关系都没有.数据库凭什么要为你们的错误而承担责任?请为自己的代码负责.我说下php中的一个解决方案(不知道为什么我不能贴代码).

$sql = "SELECT * FROM table1 WHERE ";
$cons = array();
if($xxx){
    $cons[] = "xxx = $xxx";
}
if($yyy){
    $cons[] = "xxx LIKE '$yyy%'";
}

...................

$cons = join(" AND ",$cons);
$sql  = rtrim($sql.$cons,'WHERE ');

如果1=1真的影响性能,那就让1=1从你的代码中消失吧.如果你的语言里没有join,rtrim这样功能的函数或者说连接数组都没有,那可能就是数据库的错.
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics