最近读了程序员的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 SERVER系列]读书笔记之SQL注入漏洞和SQL调优的更多相关文章

  1. 《Troubleshooting SQL Server》读书笔记-CPU使用率过高(下)

    <Troubleshooting SQL Server>读书笔记-CPU使用率过高(下) 第三章 High CPU Utilization. CPU使用率过高的常见原因 查询优化器会尽量从 ...

  2. Querying Microsoft SQL Server 2012 读书笔记:查询和管理XML数据 2 -使用XQuery 查询XML数据

    XQuery 是一个浏览/返回XML实例的标准语言. 它比老的只能简单处理节点的XPath表达式更丰富. 你可以同XPath一样使用.或是遍历所有节点,塑造XML实例的返回等. 作为一个查询语言, 你 ...

  3. Querying Microsoft SQL Server 2012 读书笔记:查询和管理XML数据 1 -使用FOR XML返回XML结果集

    XML 介绍 <CustomersOrders> <Customer custid="1" companyname="Customer NRZBB&qu ...

  4. 《Troubleshooting SQL Server》读书笔记-内存管理

    自调整的数据库引擎(Self-tuning Database Engine) 长期以来,微软都致力于自调整(Self-Tuning)的SQL Server数据库引擎,用以降低产品的总拥有成本.从SQL ...

  5. 《Troubleshooting SQL Server》读书笔记-CPU使用率过高(上)

    第三章 High CPU Utilization. CPU使用率过高问题很容易被发现,但是诊断却不是很容易.CPU使用过高很多时候会成为其它问题的替罪羊,所以在确认和故障诊断时要抽丝剥茧. 调查CPU ...

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

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

  7. 读书笔记之SQL注入漏洞和SQL调优

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

  8. C#面试题(转载) SQL Server 数据库基础笔记分享(下) SQL Server 数据库基础笔记分享(上) Asp.Net MVC4中的全局过滤器 C#语法——泛型的多种应用

    C#面试题(转载) 原文地址:100道C#面试题(.net开发人员必备)  https://blog.csdn.net/u013519551/article/details/51220841 1. . ...

  9. 《[MySQL技术内幕:SQL编程》读书笔记

    <[MySQL技术内幕:SQL编程>读书笔记 2019年3月31日23:12:11 严禁转载!!! <MySQL技术内幕:SQL编程>这本书是我比较喜欢的一位国内作者姜承尧, ...

随机推荐

  1. [设计模式]<<设计模式之禅>>工厂方法模式

    1 女娲造人的故事 东汉<风俗通>记录了一则神话故事:“开天辟地,未有人民,女娲搏黄土做人”,讲述的内容就是大家非常熟悉的女娲造人的故事.开天辟地之初,大地上并没有生物,只有苍茫大地,纯粹 ...

  2. makefile中使用变量

    makefile里的变量就像一个变量,变量的作用主要如下: (1)保存文件名列表. (2)保存编译器的参数. makefile中的变量是用一个字符串在makefile中定义的,这个文本串就是变量的值. ...

  3. http keepalive

    转载自: http://www.92csz.com/17/1152.html http keepalive 在http早期 ,每个http请求都要求打开一个tpc socket连接,并且使用一次之后就 ...

  4. iframe仿Ajax上传文件

    利用iframe框架完成文件上传 前端页面 <!doctype html> <html lang="en"> <head> <meta c ...

  5. Spring(3.2.3) - Beans(7): 延迟实例化

    默认情况下,Spring IoC 容器启动后,在初始化过程中,会以单例模式创建并配置所有使用 singleton 定义的 Bean 的实例.通常情况下,提前实例化 Bean 是可取的,因为这样在配置中 ...

  6. 第六节 ADO.NET

    ADO.NET是一组为.NET编程人员提供数据访问服务的类,封装在System.Data.dll 中,是.NET框架的一部分,它是一种数据访问技术. 使用SQLServer数据提供程序 类 说明 Sq ...

  7. DOS批处理命令-pause

    “pause”用于暂停批处理的执行器并给出提示信息,然后由用户决定是继续执行还是终端执行. 语法: pause 简单一个pause,不附带任何参数. 执行pause以后会提示一句话[按任意键继续执行] ...

  8. Android中SurfaceView的使用详解

    Android中SurfaceView的使用详解 http://blog.csdn.net/listening_music/article/details/6860786 Android NDK开发 ...

  9. (转)Hessian(C#)介绍及使用说明

    什么是Hessian? Hessian是Caucho开发的一种二进制Web Service协议.支持目前所有流行的开发平台. Hessia能干什么? hessian用来实现web服务. Hessia有 ...

  10. [GeekBand] STL与泛型编程(3)

    本篇文章主要介绍泛型算法中的变易.排序.数值算法. 一. 变易算法 所谓变易算法是指那些改变容器中的对象的操作. 1.1 copy组 template <class InputIterator, ...