原文:读书笔记之SQL注入漏洞和SQL调优

  最近读了程序员的SQL金典这本书,觉得里面的SQL注入漏洞和SQL调优总结得不错,下面简单讨论下SQL注入漏洞和SQL调优。

1. SQL注入漏洞

  由于“'1'='1'”这个表达式永远返回 true,而 true 与任何布尔值的 or 运算的结果都是 true,那么无论正确密码是什么“Password='1' or '1'='1'”的计算值永远是 true,这样恶意攻击者就可以使用任何帐户登录系统了。这样的漏洞就被称作“SQL 注入漏洞(SQL Injection)”。

  对付 SQL 注入漏洞有两种方式:过滤敏感字符和使用参数化 SQL。

  1).过滤敏感字符

  过滤敏感字符的思路非常简单,由于恶意攻击者一般需要在输入框中输入的文本一般含有 or、and、select、delete 之类的字符串片段,所以在拼接 SQL 之前检查用户提交的文本中是否含有这些敏感字符串,如果含有则终止操作。

  2).使用参数化SQL

  为运行时才能确定的用户名和密码设置了占位符,然后在运行时再设定占位符的值,在执行时 Java、C#会直接将参数化 SQL 以及对应的参数值传递给 DBMS,在 DBMS 中会将参数值当成一个普通的值来处理而不是将它们拼接到参数化 SQL 中,因此从根本上避免了 SQL 注入漏洞攻击。

2. SQL 调优

  在使用 DBMS 时经常对系统的性能有非常高的要求:不能占用过多的系统内存和CPU 资源、要尽可能快的完成的数据库操作、要有尽可能高的系统吞吐量。如果系统开发出来不能满足要求的所有性能指标,则必须对系统进行调整,这个工作被称为调优。

  SQL 调优的基本原则

  “二八原理”是一个普遍的真理,特别是在计算机的世界中表现的更加明显,那就是 20%的代码的资源消耗占用了 80%的总资源消耗。SQL 语句也是一种代码,因此它也符合这个原理。在进行 SQL 调优的时候应该把主要精力放到这 20%的最消耗系统资源的 SQL 语句中,不要想把所有的 SQL 语句都调整到最优状态。

  索引是数据库调优的最根本的优化方法。

  常用的SQL调优方法:

  1) 创建必要的索引

  2) 使用预编译查询

  程序中通常是根据用户的输入来动态执行 SQL 语句,这时应该尽量使用参数化SQL,这样不仅可以避免 SQL 注入漏洞攻击,最重要数据库会对这些参数化 SQL 执行预编译。

  3) 调整 WHERE 子句中的连接顺序

  DBMS 一般采用自下而上的顺序解析 WHERE 子句,根据这个原理,表连接最好写在其他 WHERE 条件之前,那些可以过滤掉最大数量记录。

  比如下面的 SQL 语句性能较差: SELECT *   FROM T_Person WHERE   FSalary > 50000  AND     FPosition= ‘MANAGER’  AND     25 < (SELECT COUNT(*) FROM T_Manager WHERE FManagerId=2);

  我们将子查询的条件放到最前面,下面的 SQL 语句性能比较好: SELECT *   FROM T_Person WHERE   25 < (SELECT COUNT(*) FROM T_Manager WHERE FManagerId=2) AND FSalary > 50000  AND     FPosition= ‘MANAGER’ ;

  4) SELECT 语句中避免使用'*'

  SELECT  *比较简单,但是除非确实需要检索所有的列,否则将会检索出不需要的列,这回增加网络的负载和服务器的资源消耗;即使确实需要检索所有列,也不要使用SELECT *,因为这是一个非常低效的方法,DBMS 在解析的过程中,会将*依次转换成所有的列名,这意味着将耗费更多的时间。

  5) 尽量将多条 SQL 语句压缩到一句 SQL 中

  每次执行 SQL 的时候都要建立网络连接、进行权限校验、进行 SQL 语句的查询优化、发送执行结果,这个过程是非常耗时的,因此应该尽量避免过多的执行 SQL 语句,能够压缩到一句 SQL 执行的语句就不要用多条来执行。

  6) 用 Where 子句替换 HAVING 子句

  避免使用 HAVING 子句,因为 HAVING  只会在检索出所有记录之后才对结果集进行过滤。如果能通过 WHERE 子句限制记录的数目,那就能减少这方面的开销。HAVING  中的条件一般用于聚合函数的过滤,除此而外,应该将条件写在 WHERE 子句中。

  7) 使用表的别名

  当在 SQL 语句中连接多个表时,请使用表的别名并把别名前缀于每个列名上。这样就可以减少解析的时间并减少那些由列名歧义引起的语法错误。

  8) 用 EXISTS 替代 IN

  在查询中,为了满足一个条件,往往需要对另一个表进行联接,在这种情况下,使用 EXISTS 而不是 IN 通常将提高查询的效率,因为 IN 子句将执行一个子查询内部的排序和合并。

  9) 用表连接替换 EXISTS

  通常来说,表连接的方式比 EXISTS 更有效率,因此如果可能的话尽量使用表连接替换 EXISTS。

  10) 避免在索引列上使用计算

  在 WHERE 子句中,如果索引列是计算或者函数的一部分,DBMS 的优化器将不会使用索引而使用全表扫描。

  11) 用 UNION ALL  替换 UNION

  当 SQL 语句需要 UNION 两个查询结果集合时,即使检索结果中不会有重复的记录,如果使用 UNION 这两个结果集同样会尝试进行合并,然后在输出最终结果前进行排序。 因此,如果检索结果中不会有重复的记录的话,应该用 UNION ALL 替代 UNION,这样效率就会因此得到提高。

  12) 避免隐式类型转换造成的全表扫描

  13) 防止检索范围过宽

  如果 DBMS 优化器认为检索范围过宽,那么它将放弃索引查找而使用全表扫描。下面是几种可能造成检索范围过宽的情况: 使用 IS NOT NULL 或者不等于判断,可能造成优化器假设匹配的记录数太多。 使用 LIKE 运算符的时候,"a%"将会使用索引,而"a%c"和"%c"则会使用全表扫描,因此"a%c"和"%c"不能被有效的评估匹配的数量。

  

  如果您有什么问题,欢迎在下面评论,我们一起讨论,谢谢~

  如果您觉得还不错,不妨点下右下方的推荐,有您的鼓励我会继续努力的~

  

读书笔记之SQL注入漏洞和SQL调优的更多相关文章

  1. [SQL SERVER系列]读书笔记之SQL注入漏洞和SQL调优

    最近读了程序员的SQL金典这本书,觉得里面的SQL注入漏洞和SQL调优总结得不错,下面简单讨论下SQL注入漏洞和SQL调优. 1. SQL注入漏洞 由于“'1'='1'”这个表达式永远返回 true, ...

  2. SQL注入漏洞和SQL调优SQL注入漏洞和SQL调优

    SQL注入漏洞和SQL调优 最近读了程序员的SQL金典这本书,觉得里面的SQL注入漏洞和SQL调优总结得不错,下面简单讨论下SQL注入漏洞和SQL调优. 1. SQL注入漏洞 由于“'1'='1'”这 ...

  3. Java程序性能优化读书笔记(一):Java性能调优概述

    程序性能的主要表现点: 执行速度:程序的反映是否迅速,响应时间是否足够短 内存分配:内存分配是否合理,是否过多地消耗内存或者存在内存泄漏 启动时间:程序从运行到可以正常处理业务需要花费多少时间 负载承 ...

  4. 简单分析什么是SQL注入漏洞

    现在很多人在入侵的过程中基本都是通过SQL注入来完成的,但是有多少人知道为什么会有这样的注入漏洞呢?有的会随口说着对于字符的过滤不严造成的.但是事实是这样吗?我们学这些,不仅要知其然,更要知其所以然! ...

  5. 什么是简单的分析SQL注入漏洞

    如今非常多人在入侵的过程中基本都是通过SQL注入来完毕的,可是有多少人知道为什么会有这种注入漏洞呢?有的会随口说着对于字符的过滤不严造成的. 可是事实是这样吗?我们学这些.不仅要知其然.更要知其所以然 ...

  6. SQL注入漏洞原理

    系统中安全性是非常重要的,为了保证安全性很多解决方案被应用到系统中,比如架设防火墙防止数据库服务器直接暴露给外部访问者.使用数据库的授权机制防止未授权的用户访问数据库,这些解决方案可以很大程度上避免了 ...

  7. Statement对象sql注入漏洞的问题

    现在通过mysql以及oracle来测试sql注入  漏洞 mysql中的注释#    oracle中的注释为-- 所以注入漏洞就产生了 //登录测试 public void login()throw ...

  8. SQL注入漏洞篇

    一篇SQL注入漏洞汇总,更新中-- 如有缺陷 望大佬指正 SQL注入产生的原因? 当程序执行逻辑时没有对用户输入的参数做过滤处理,使参数直接与后台数据库产生逻辑交互,即SQL注入黑客就可以利用各种SQ ...

  9. sql注入学习笔记,什么是sql注入,如何预防sql注入,如何寻找sql注入漏洞,如何注入sql攻击 (原)

    (整篇文章废话很多,但其实是为了新手能更好的了解这个sql注入是什么,需要学习的是文章最后关于如何预防sql注入) (整篇文章废话很多,但其实是为了新手能更好的了解这个sql注入是什么,需要学习的是文 ...

随机推荐

  1. SE 2014年4月22日(二)

    如图配置: 网络中存在三个公有AS 其中AS200使用了 BGP联盟技术(如图配置) 在AS 100 中R1上起源了四条BGP路由,(1)要求全网BGP设备均能够正常学习 (2)要求:(使用BGP团体 ...

  2. 京东商城招聘自动调价系统架构师 T4级别

    岗位级别:T4 岗位职责: 1.负责自动调价系统的架构设计 2.负责自动调价的预测.相关性算法设计 3.核心代码编写,代码review 任职要求: 1.熟悉数据挖掘.机器学习理论和算法 2.熟悉海量数 ...

  3. 使用NFS安装oracle软件

    昨天.使用openfiler创建nas存储系统,安装oracle软件,在所有正面最好,要创建一个数据库时报ora错,原来使用nfs安装oracle数据库,mount选项有特殊要求,如以下.以备查: R ...

  4. String ,StringBuffer,StringBuilder精髓比較

    1. 在运行速度方面的比較:StringBuilder > StringBuffer > String 2. StringBuffer与StringBuilder.他们是字符串变量,是可改 ...

  5. zend studio 10 实现代码自动换行

    在一篇zend framework 的PHP编码标准的文章中看到了这么一段: 一行 80 字符以内是比较合适,就是说,ZF 的开发者应当努力在可能的情况下保持每行代码少于 80 个字符,在有些情况下, ...

  6. android中listview分页载入数据

    前段时间做的新浪微博项目一直想实现listview分页载入数据,今天最终实现了,哈哈!感觉挺好的,今天又写了个demo给大家分享下. 首先说下listview的优化方案,这也是面试中常考的题目.优化方 ...

  7. Hyper-V笔记

    Hyper-V的网络架设 Hyper-V中创建“虚拟网络”(可看成交换机)会在物理机中创建相应的虚拟网卡.Hyper-V安装好后会默认创建一个“本地连接-虚拟网络”对应的虚拟网卡给物理机使用,原本的本 ...

  8. Android Material Design-Creating Lists and Cards(创建列表和卡)-(三)

    转载请注明出处:http://blog.csdn.net/bbld_/article/details/40430319 翻译自:http://developer.android.com/trainin ...

  9. Java使用LdAP获取AD域用户

    随着我们的习大大上台后,国家在网络信息安全方面就有了非常明显的改变!所以如今好多做网络信息安全产品的公司和须要网络信息安全的公司都会提到用AD域server来验证,这里就简单的研究了一下! 先简单的讲 ...

  10. RedGate 工具SQLMultiScript1.1

    原文:RedGate 工具SQLMultiScript1.1 RedGate 工具SQLMultiScript1.1 SQLMultiScript是一个脚本分发工具,当你写好了一个SQL脚本之后,你需 ...