网上有不少人提出过类似的问题:“看到有人写了where 1=1这种sql,究竟是什么意思?”。事实上使用这种使用方法的开发者一般都是在使用动态数组的sql。

让我们想象例如以下的场景:用户要求提供一个灵活的查询界面来依据各种复杂的条件查询员工信息,界面例如以下图:

界面中列出了四个查询条件,包含按工号查询、按姓名查询、按年两查询以及按工资查询。每一个查询条件前都有个复选框,假设复选框被选中,则表示将其作为一个过滤条件。

比方上图就表示“检索工号介于001和008之间、姓名中含有J而且工资介于3000到6000的员工信息”。

假设不选中姓名前的复选框,比方下图表示“检索工号介于001和008之间

而且工资介于3000到6000的员工信息”:

假设全部的复选框都不选中,则表示“检索全部员工信息”,比方下图:

这里的数据检索与前面的检索不一样,由于前边样例中的数据检索的过滤条件都是确定的。而这里的过滤条件则随着用户设置的不同而有变化,这时就要依据用户的设置来动态

组装sql了。当不选中年龄前的复选框的时候要使用以下的SQL语句:

SELECT * FROM T_Employee
WHERE FNumber BETWEEN '001' AND '008'
AND FName LIKE '%J%'
AND FSalary BETWEEN 3000 AND 6000

而假设不选中姓名和年龄前的复选框的时候就要使用以下的SQL语句:

SELECT * FROM T_Employee
WHERE FNumber BETWEEN '001' AND '008'
AND FSalary BETWEEN 3000 AND 6000

而假设将全部的复选框都不选中的时候就要使用以下的SQL语句:

SELECT * FROM T_Employee

要实现这样的动态的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 FName LIKE '%"+姓名文本框内容+"%'");
}
if(年龄复选框选中)
{
sql.appendLine("AND FAge BETWEEN "+年龄文本框1内容+" AND "+年龄文本框2
内容);
}
executeSQL(sql);

这样假设不选中姓名和年龄前的复选框的时候就会运行以下的SQL语句:

SELECT * FROM T_Employee WHERE 1=1
AND FNumber BETWEEN 'DEV001' AND 'DEV008'
AND FSalary BETWEEN 3000 AND 6000

而假设将全部的复选框都不选中的时候就会运行以下的SQL语句:

SELECT * FROM T_Employee WHERE 1=1

这看似很优美的攻克了问题。殊不知这样很可能会造成很大的性能损失,由于使用加入了“1=1”的过滤条件以后数据库系统就无法使用索引等查询优化策略。数据库系统将

会被迫对每行数据进行扫描(也就是全表扫描)以比較此行是否满足过滤条件。当表中数据量比較大的时候查询速度会很慢。

因此假设数据检索对性能有比較高的要求就不要

使用这样的“简便”的方式。以下给出一种參考实现。伪代码例如以下:

private void doQuery()
{
Bool 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("FName LIKE '%"+姓名文本框内容+"%'");
}
if(年龄复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FAge BETWEEN "+年龄文本框1内容+" AND "+年龄文本框2
内容);
}
executeSQL(sql);
}
private Bool appendWhereIfNeed(StringBuilder sql,Bool hasWhere)
{
if(hasWhere==false)
{
sql. appendLine("WHERE");
}
else
{
sql. appendLine("AND");
}
}

低效能的”where1=1”的更多相关文章

  1. PLSQL_低效SQL的识别和查询汇总(案例)

    2014-12-18 Created By BaoXinjian

  2. 如何找出MySQL数据库中的低效SQL语句

    面对业务的迅猛发展,DBA的一项重要工作就是及时发现数据库中的低效SQL语句,有的可以立刻着手解决(比如缺少合适的索引),有的需要尽快反馈给开发人员进行修改. MySQL数据库有几个配置选项可以帮助我 ...

  3. 通过dbms_xplan.display_cursor识别低效的执行计划

    dbms_xplan.display_cursor定义: function display_cursor(sql_id           varchar2 default  null,        ...

  4. 一个令人困惑的低效SQL

    整理之前的优化案例,觉得下面这个应该是开发很难发现也会很困惑的一个低效SQL. 看下面这个SQL.你看到这个SQL会不会感觉很正常.其实我刚看到也觉得正常得不得了.但是测试后它确实效率很低.selec ...

  5. 低效的SQL引发的cache buffers chains latch

    1.低效的SQL 低效的SQL语句时发生cache buffers chains 锁存器争用的最重要原因.多个进程同时扫描大范围的索引或表时,可能广泛 地发生cache buffers chains ...

  6. SQL调优学习之——sqlserver分页从低效到高效

    背景 首先感谢网友@aixuexi 在评论中的提醒,原博文介绍的几种都不是最高效,现已修改加入另一种更高效的方法. 以前都是使用mysql和oracle,对sqlserver的使用不多.最近因项目原因 ...

  7. 秒杀场景下MySQL的低效(转)

    秒杀场景下MySQL的低效 2016-01-14 17:12 178人阅读 评论(0) 收藏 举报 最近业务试水电商,接了一个秒杀的活.之前经常看到淘宝的同行们讨论秒杀,讨论电商,这次终于轮到我们自己 ...

  8. 【转载】秒杀场景下MySQL的低效原因和改进以及Redis的处理

    分享的PPT在如下网址: http://www.doc88.com/p-4199037770087.html 秒杀场景下mysql的低效原因和改进 另外有一个篇文章是针对以上内容的总结: http:/ ...

  9. CPU和GPU双低效,摩尔定律之后一万倍 ——写于TPU版AlphaGo重出江湖之际

    本文来自计算机体系结构专家王逵.他认为,“摩尔定律结束之后,性能提升一万倍”不会是科幻,而是发生在我们眼前的事实.   2008年,<三体2:黑暗森林>里写到:   真的很难,你冬眠后不久 ...

  10. 使用std::function改善模板的低效性

    泛型编程中,模板会根据传入类型的不同,生成多种实例,相对低效. 模板编程: #include <iostream> using namespace std; //未使用函数包装器 temp ...

随机推荐

  1. 一个三年Android开发的总结-开篇

    一个三年Android开发的总结-开篇 转眼间全职从事Android开发已有三年,想把这一阶段的积累总结记录并展现出来,作为Android开发必备的知识,希望对有一定Android开发基础的人进阶有裨 ...

  2. java里面包的重要性-管理类文件

    包的必要性 包是用来给java源文件分门别类的,java中一个包在windows下就是一个文件夹.包的全限定名是从根文件夹開始的(\src文件夹)以点号作为分隔符,包名和包名之间使用点号隔开,java ...

  3. Linux 程序设计学习笔记----Linux下文件类型和属性管理

    转载请注明出处:http://blog.csdn.net/suool/article/details/38318225 部分内容整理自网络,在此感谢各位大神. Linux文件类型和权限 数据表示 文件 ...

  4. 数组进行多少次OP操作,才干有序

    1 题目描写叙述: 有一个数组:2,1,4,3.对于数组,有一种操作op(idx):将该index相应的数字移到首位.比方: op(3):  2 1 43 -> 3 2 1 4 op(1):   ...

  5. 从乐视和小米“最火电视”之战 看PR传播策略

        今年的双11够热闹.一方面,阿里.京东.国美.苏宁等电商巨头卯足了劲儿.试图在双11期间斗个你死我活,剑拔弩张的气势超过了以往不论什么一场双11:还有一方面.不少硬件厂商.家电企业也来凑双11 ...

  6. 英语发音规则---W字母

    英语发音规则---W字母 一.总结 一句话总结: 1.W在单词开头发[w]? week [wiːk] n. 周,星期 win [wɪn] vt. 赢得 wake [weɪk] vi. 醒来 sweet ...

  7. Java基础之关键字

    一.Java关键字总览 基本数据类型(9):boolean.char.byte.short.int.long.float.double.null 变量引用(2):super.this 类.方法.变量修 ...

  8. vue.js和node.js的认识

    首先vue.js 是库,不是框架,不是框架,不是框架. Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据. Vue.js 的核心是一个允许你 ...

  9. c++面向对象程序设计 谭浩强 第三章答案

    2: #include <iostream> using namespace std; class Date {public: Date(int,int,int); Date(int,in ...

  10. 视图 Model转集合

    @{    Layout = null;}@using MvcApplication2.Models <!DOCTYPE html> <html><head>    ...