低效能的”where1=1”
网上有不少人提出过类似的问题:“看到有人写了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”的更多相关文章
- PLSQL_低效SQL的识别和查询汇总(案例)
2014-12-18 Created By BaoXinjian
- 如何找出MySQL数据库中的低效SQL语句
面对业务的迅猛发展,DBA的一项重要工作就是及时发现数据库中的低效SQL语句,有的可以立刻着手解决(比如缺少合适的索引),有的需要尽快反馈给开发人员进行修改. MySQL数据库有几个配置选项可以帮助我 ...
- 通过dbms_xplan.display_cursor识别低效的执行计划
dbms_xplan.display_cursor定义: function display_cursor(sql_id varchar2 default null, ...
- 一个令人困惑的低效SQL
整理之前的优化案例,觉得下面这个应该是开发很难发现也会很困惑的一个低效SQL. 看下面这个SQL.你看到这个SQL会不会感觉很正常.其实我刚看到也觉得正常得不得了.但是测试后它确实效率很低.selec ...
- 低效的SQL引发的cache buffers chains latch
1.低效的SQL 低效的SQL语句时发生cache buffers chains 锁存器争用的最重要原因.多个进程同时扫描大范围的索引或表时,可能广泛 地发生cache buffers chains ...
- SQL调优学习之——sqlserver分页从低效到高效
背景 首先感谢网友@aixuexi 在评论中的提醒,原博文介绍的几种都不是最高效,现已修改加入另一种更高效的方法. 以前都是使用mysql和oracle,对sqlserver的使用不多.最近因项目原因 ...
- 秒杀场景下MySQL的低效(转)
秒杀场景下MySQL的低效 2016-01-14 17:12 178人阅读 评论(0) 收藏 举报 最近业务试水电商,接了一个秒杀的活.之前经常看到淘宝的同行们讨论秒杀,讨论电商,这次终于轮到我们自己 ...
- 【转载】秒杀场景下MySQL的低效原因和改进以及Redis的处理
分享的PPT在如下网址: http://www.doc88.com/p-4199037770087.html 秒杀场景下mysql的低效原因和改进 另外有一个篇文章是针对以上内容的总结: http:/ ...
- CPU和GPU双低效,摩尔定律之后一万倍 ——写于TPU版AlphaGo重出江湖之际
本文来自计算机体系结构专家王逵.他认为,“摩尔定律结束之后,性能提升一万倍”不会是科幻,而是发生在我们眼前的事实. 2008年,<三体2:黑暗森林>里写到: 真的很难,你冬眠后不久 ...
- 使用std::function改善模板的低效性
泛型编程中,模板会根据传入类型的不同,生成多种实例,相对低效. 模板编程: #include <iostream> using namespace std; //未使用函数包装器 temp ...
随机推荐
- 数据可视化利器pyechart和matplotlib比较
python中用作数据可视化的工具有多种,其中matplotlib最为基础.故在工具选择上,图形美观之外,操作方便即上乘. 本文着重说明常见图表用基础版matplotlib和改良版pyecharts作 ...
- 第一篇、Android Supersu 权限管理定制,隐藏过滤权限,指定APP最高权限
近期有个需求,在预装ROM的时候,须要权限,可是又不同意全部的应用都有权限,仅仅同意自己的应用有最高的权限(当然没有系统签名情况下). 所以.编译了CM 提取了supersu进行了二次定制,让他进行权 ...
- CSDN的技术问题
说CSDN是国内最大最好的技术论坛.预计不会有人反对,可是...CSDN的人,如管理员懂技术吗? 假设您长期在CSDN混.您就会发现他们相当懂得......强奸技术!
- Xcode6 引入第三方静态库project的方法
首先.介绍一下把在当前project中引入其它依赖project的方法: 第一:把其它项目project加入到现有project做法: 定义: FPro 现有project == 父project C ...
- Oracle 11G R2 RAC中的scan ip 的用途和基本原理
Oracle 11G R2 RAC增加了scan ip功能,在11.2之前,client链接数据库的时候要用vip,假如你的cluster有4个节点,那么客户端的tnsnames.ora中就对应有四个 ...
- 杂项:WCF
ylbtech-杂项:WCF Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台. 整合了 ...
- 39.Qt XML
1.使用QXmlStreamReader读取XML,可以读取内存中容纳不了的特大文件,或者读取在XML文档中定制的文档的内容. xml文件(in1.xml) <?xml version=&quo ...
- SQL Server 查询所有包含某文本的存储过程、视图、函数
• 方法一:查询所有包含某文本的存储过程.视图.函数 SELECT * from sysobjects o, syscomments s where o.id = s.id AND text LIK ...
- MVC的一些常用特性,持续更新中。。。
1. @MvcHtmlString.Create("<option value='1'>火星</option>") //渲染Html
- UWP 开发APP准备工作
每新建一个UWP之后,都要进行一番相同的处理步骤,才能使Mobile的使用体验更好,故总结如下: 1.订阅Mobile后退导航事件 在App.xaml.cs文件中OnLaunched方法中添加 Sys ...