锁定老帖子 主题:低效的where 1=1
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-07-12
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分... |
|
返回顶楼 | |
发表时间:2010-07-12
抛出异常的爱 写道 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的..??? |
|
返回顶楼 | |
发表时间:2010-07-12
最后修改:2010-07-12
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的..??? 莫非这位大锅您用的String? String s = "a"; for(int i=0;i<50;i++){ s+=s; System.out.println(i); } 可以简单走一下。你会发现在不改变jvm内存的情况下,第20次会出现什么 |
|
返回顶楼 | |
发表时间:2010-07-12
最后修改:2010-07-12
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,不是个好习惯。 |
|
返回顶楼 | |
发表时间:2010-07-12
select * from table where 1=1因为table中根本就没有名称为1的字段,所以该SQL等效于select * from table,这个SQL语句很明显是全表扫描,需要大量的IO操作,数据量越大越慢,建议查询时增加必输项,即where 1=1后面追加一些常用的必选条件,并且将这些必选条件建立适当的索引,效率会大大提高
PS:这不是SQL写法的问题,也不是数据库的问题,是自己程序逻辑的问题 |
|
返回顶楼 | |
发表时间:2010-07-12
xiaojing3517 写道 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的..??? 莫非这位大锅您用的String? String s = "a"; for(int i=0;i<50;i++){ s+=s; System.out.println(i); } 可以简单走一下。你会发现在不改变jvm内存的情况下,第20次会出现什么 爷们 你可以用StringBuilder试一下你的例子 这个例子中拼装的字符串的量是巨大的 循环到20几的时候 已经是千万级的了! 虽然StringBuilder/StringBuffer拼装字符串上是有很大的优势 但这个例子有些牵强了 |
|
返回顶楼 | |
发表时间:2010-07-12
maoone2003 写道 select * from table where 1=1因为table中根本就没有名称为1的字段,所以该SQL等效于select * from table,这个SQL语句很明显是全表扫描,需要大量的IO操作,数据量越大越慢,建议查询时增加必输项,即where 1=1后面追加一些常用的必选条件,并且将这些必选条件建立适当的索引,效率会大大提高
PS:这不是SQL写法的问题,也不是数据库的问题,是自己程序逻辑的问题 ---------------------------------------------- select * from table where 1=1因为table中根本就没有名称为1的字段,所以该SQL等效于select * from table 等效? |
|
返回顶楼 | |
发表时间:2010-07-12
最后修改:2010-07-12
nanquan 写道 xiaojing3517 写道 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的..??? 莫非这位大锅您用的String? String s = "a"; for(int i=0;i<50;i++){ s+=s; System.out.println(i); } 可以简单走一下。你会发现在不改变jvm内存的情况下,第20次会出现什么 爷们 你可以用StringBuilder试一下你的例子 这个例子中拼装的字符串的量是巨大的 循环到20几的时候 已经是千万级的了! 虽然StringBuilder/StringBuffer拼装字符串上是有很大的优势 但这个例子有些牵强了 String、StringBuffer。笑而不语 |
|
返回顶楼 | |
发表时间:2010-07-12
maoone2003 写道 select * from table where 1=1因为table中根本就没有名称为1的字段,所以该SQL等效于select * from table,这个SQL语句很明显是全表扫描,需要大量的IO操作,数据量越大越慢,建议查询时增加必输项,即where 1=1后面追加一些常用的必选条件,并且将这些必选条件建立适当的索引,效率会大大提高
PS:这不是SQL写法的问题,也不是数据库的问题,是自己程序逻辑的问题 ------------------- PS:这不是SQL写法的问题,也不是数据库的问题,是自己程序逻辑的问题 很赞成 |
|
返回顶楼 | |
发表时间:2010-07-12
这个例子太邪恶了。
s+=s; 俺还以为s+="a" StringBuilder还是要出错啊。OutOfMemoryError必须滴 |
|
返回顶楼 | |