低效能的”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 ...
随机推荐
- [HTML5] Why ARIA?
For some reason, you build a custom checkbox component, if without ARIA in mind, basiclly this site ...
- Android error--No implementation found for native Lcomd
在利用NDK编译Cpp执行时,出现了No implementation found for native Lcom等错误,调试好久,才发现 XXX.h和XXX.cpp.在XXX.cpp里#includ ...
- MyEclipse改动内存大小
方式一网上说的(没有測试过): 找到MyEclipse的安装文件夹,一般假设不改动的话默觉得C:\MyEclipse10.1\Genuitec\MyEclipse 10.1有一个myeclipse.i ...
- SharePoint 创建网站地图树视图及格式枚举截图
SharePoint 创建网站地图树视图及格式枚举截图 SharePoint首页隐藏掉左側导航以后,假设要以树视图呈现站点地图也非常easy. 仅仅须要复制v4.mas ...
- 个人作业—Alpha项目测试
这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass2 这个作业要求在哪里 https://edu.cnblo ...
- 关于ubuntu中文输入调用不出来的解决办法,具体如正文。
卸载了 fcitx sudo apt-get remove fcitx 重启 sudo reboot 重新安装 fcitxsudo apt-get install fcitx 安装拼音输入法sudo ...
- 流式计算新贵Kafka Stream设计详解--转
原文地址:https://mp.weixin.qq.com/s?__biz=MzA5NzkxMzg1Nw==&mid=2653162822&idx=1&sn=8c4611436 ...
- Java NIO(五)套接字通道
Socket通道 Socket通道和文件通道有着不一样的特征: Socket通道类可以运行于非阻塞模式,并且是可选的.这两个特征可以激活大程序(如网络服务和中间件组件)巨大的可伸缩性和灵活性,因此再也 ...
- html 编码与解码
var HtmlUtil = { /*1.用浏览器内部转换器实现html转码*/ htmlEncode:function (html){ //1.首先动态创建一个容器标签元素,如DIV var tem ...
- AlertDialog的使用
1.Alertdialog的几种形式: 2.第一种:简单对话框 AlertDialog.Builder localBuilder = new AlertDialog.Builder(this); lo ...