`
awtqty_zhang
  • 浏览: 92573 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

读《程序员的SQL 金典》笔记 ------- 低效的“WHERE 1=1”

 
阅读更多

低效的“WHERE 1=1”

在工作中我们经常遇到根据用户输入不同而改变数据查询条件的需要,如:

根据用户输入的信息查询员工信息:

1、当工号项不为空时,根据输入的工号查询;

2、当年龄项不为空时,根据输入的年龄阶段查询;

3、当工资范围项不为空时,需对员工的工资项进行过滤等。

这里的过滤条件则随着用户设置的不同而有变化,这时就要根据用户的输入来动态组装SQL了。

 

要实现这种动态的SQL语句拼装,我们可以在宿主语言中建立一个字符串,然后逐个判断各个条件是否满足来向这个字符串中添加SQL语句片段。这里有一个问题就是当有条件的时候SQL语句是含有WHERE子句的,而当所有的条件都不满足的时候就没有WHERE子句了,因此在添加每一个过滤条件判断的时候都要判断是否已经存在WHERE语句了,如果没有WHERE语句则添加WHERE语句。这使得用起来非常麻烦,“聪明的程序员是会偷懒的程序员”,因此开发人员想到了一个捷径:为SQL语句指定一个永远为真的条件语句(比如“1=1”),这样就不用考虑WHERE语句是否存在的问题了。伪代码如下:

 

String sql = " SELECT * FROM T_Employee WHERE 1=1 ";
if(工号){
    sql.appendLine("AND FNumber BETWEEN '"+工号文本框1内容+"' AND '"+工号文本框2内容+"'");
}
if(年龄){
    sql.appendLine("AND FAge BETWEEN "+年龄文本框1内容+" AND "+年龄文本框2内容);
}
if(工资){
    sql.appendLine("AND FSalary BETWEEN "+工资文本框1内容+" AND "+工资文本框2内容);
}
executeSQL(sql);

 

这看似非常优美的解决了问题,殊不知这样很可能会造成非常大的性能损失,因为使用添加了“1=1”的过滤条件以后数据库系统就无法使用索引等查询优化策略,数据库系统将会被迫对每行数据进行扫描(也就是全表扫描)以比较此行是否满足过滤条件,当表中数据量比较大的时候查询速度会非常慢。因此如果数据检索对性能有比较高的要求就不要使用这种“简便”的方式。下面给出一种参考实现,伪代码如下:

 

private void doQuery(){
    boolean hasWhere = false;
    StringBuilder sql = new StringBuilder(" SELECT * FROM T_Employee");
    if(工号){
        hasWhere = appendWhereIfNeed(sql, hasWhere);
        sql.appendLine("FNumber BETWEEN '"+工号文本框1内容+"' AND '"+工号文本框2内容+"'");
    }
    if(年龄){
        hasWhere = appendWhereIfNeed(sql, hasWhere);
        sql.appendLine("FAge BETWEEN "+年龄文本框1内容+" AND "+年龄文本框2内容);
    }
    if(工资){
	hasWhere = appendWhereIfNeed(sql, hasWhere);
        sql.appendLine("FSalary BETWEEN "+工资文本框1内容+" AND "+工资文本框2内容);
    }
    executeSQL(sql);
}
private boolean appendWhereIfNeed(StringBuilder sql,boolean hasWhere){
    if(!hasWhere){
        sql.appendLine(" WHERE ");
    } else{
        sql.appendLine(" AND ");
    }
    return true;
}
分享到:
评论

相关推荐

    黑马程序员-SpringCloud-学习笔记-03-Eureka注册中心

    黑马程序员-SpringCloud-学习笔记-03-Eureka注册中心

    程序员的SQL金典-PDF

    《程序员的SQL金典》分为3部分:第1部分为基础篇,主要讲解数据库对增、删、改、查等SQL的支持,给出了这些SQL的应用案例;第2部分为进阶篇,讲解了函数、子查询、表连接、不同DBMS中的SQL语法差异、SQL调优、NULL值...

    程序员SQL 金典(完整版) part3

    程序员 SQL 金典 完整版 最给力的 完整版

    程序员单页简历模板-92篇.rar

    程序员单页简历模板-92篇程序员单页简历模板-92篇程序员单页简历模板-92篇程序员单页简历模板-92篇程序员单页简历模板-92篇程序员单页简历模板-92篇程序员单页简历模板-92篇程序员单页简历模板-92篇程序员单页简历...

    Sharp-ORM 2007 1.0

    通过ORM让程序员彻底摆脱书写SQL的低效,提高SQL的执行效率。 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=Sharp-ORM公开源码地址: http://download.csdn.net/source/336341 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    Sharp-ORM 2007 (1.5) for Oracle

    通过ORM让程序员彻底摆脱书写SQL的低效,提高SQL的执行效率。 Ver 1.5 - Release date 2007-06-20 Now Support Oracle Database -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=Sharp-ORM公开源码地址: ...

    黑马程序员-SpringCloud-学习笔记-02-微服务拆分及远程调用

    黑马程序员-SpringCloud-学习笔记-02-微服务拆分及远程调用

    程序员面试金典-第五版

    资源名称:程序员面试金典-第五版资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    黑马程序员-SpringCloud-学习笔记01-认识微服务

    黑马程序员-SpringCloud-学习笔记01-认识微服务

    程序员的SQL金典(完整版)

    程序员 SQL 金典 完整版 最给力的 完整版

    Sharp-ORM 2007 (1.2) for MSSQL Server

    通过ORM让程序员彻底摆脱书写SQL的低效,提高SQL的执行效率。 Ver 1.2 - Release date 2007-04-16 Internal paged datasource support IDataReader now. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=Sharp-ORM公开...

    程序员的SQL金典 PDF扫描版

    根据提供的文件信息,“程序员的SQL金典 PDF扫描版”,我们可以推断这是一本关于SQL编程技术的专业书籍。虽然具体的书籍内容无法直接获取,但结合标题、描述以及标签("mysql"),可以合理推测这本书主要围绕MySQL...

    程序员面试金典-中文第五版 pdf

    程序员面试金典-中文第五版 pdf 程序员面试金典-中文第五版 pdf

    简历模板-程序员-通用-精选

    简历模板-程序员-通用-精选简历模板-程序员-通用-精选简历模板-程序员-通用-精选简历模板-程序员-通用-精选简历模板-程序员-通用-精选简历模板-程序员-通用-精选简历模板-程序员-通用-精选简历模板-程序员-通用-精选...

Global site tag (gtag.js) - Google Analytics