• SQL查询安全性及性能优化


    SQL注入的原理

    什么SQL注入

    SQL代码插入到应用程序的输入参数中,之后,SQL代码被传递到数据库执行。从而达到对应用程序的攻击目的。

    注入原理

    clip_image002

    常见攻击方法

    检测是否可以注入【检测注入点】

    示例:http://192.168.0.1/temp.aspx?id=a or 1=1--

    如果上面语句可以执行说明可以实现注入,则可以

    利用系统过程、系统表注入数据库

    示例【给系统添加一个用户,黑客可以实现远程登录控制服务器】:http://192.168.0.1/temp.aspx?id=1;exec xp_cmdshell 'net user admin 123456 /add'

    绕过程序的限制

    示例:程序中往往限制单引号的数据,但是黑客传入单引号的ASCII

    跨站点注入

    Web页面挂某些恶意的HTMLJavaScript代码

    防范SQL注入

    限制错误信息的输出,避免错误信息的输出使得黑客知道网站的技术实现采用什么数据库,采用什么平台

    示例:在Web.config文件中设置

    <customErrors mode="On" defaultRedirect="error.aspx">

    </customErros>

    限制访问数据库账号的权限

    在开发应用系统的时候就应该限制,给程序最小访问数据库的权限

    使用参数命令传递参数

    不要使用拼接字符串的方式构造SQL语句而采用参数命令

    使用存储过程

    存储过程在数据库中

    只能执行存储过程中固定的代码

    限制输入长度

    防止黑客输入超大字符串,导致服务器瘫痪

    防止黑客输入较长的恶意脚本等

    实现方法:文本框的MaxLength属性

    URL重写技术

    示例: http://testWeb/news.aspx?id=111

    重写成:http://testWeb/10101111.html

    传递参数尽量不用字符串

    http://testWeb/news.aspx?id=111 and 1=1【黑色部分给了SQL注入的机会】

    SQL优化

    为什么要优化

    开发是对性能考虑不多【技术差、项目工期紧等原因没有考虑性能问题】

    系统运行中,数据量扩大,访问量增多,蹩脚的SQL危害开始显露

    低效SQL的危害

    系统响应变慢,软件开发中的8秒定律,当打开一个软件或网页超过8秒时间还没有显示,则响应太慢。

    死锁,当不同用户都访问某些资源的时候SQL语句不当导致死锁

    客户失去信心,软件失败

    低效SQL低效在哪里?

    u性能低下的根源

    l硬件原因,数据库的配置不合理,数据库的数据文件和日志文件没有分磁盘存放,会极大影响IO性能

    l没有建立索引,或者SQL没有走索引。在千万级数据的表上建索引是很有必要的。

    lSQL过于复杂,过长的SQL语句满足程序需求但是影响性能。子查询嵌套过多对性能有影响,查询关联的表特别多也影响性能

    l频繁访问数据等等

    SQL如何被SQLServer执行的

    SQL执行原理

    clip_image004

    l解释:首先解释SQL语句【语法是否正确】

    l解析:检验语句的出现的对象是否有效【进行一个解析,要检查对象所有权的权限】

    l优化:【检查SQL语句是否能够使用索引,SQL语句如何执行效率高,制定一个执行计划】

    l编译:

    l执行SQL语句:【把编译过的查询要求提交并进行处理】

    如何优化SQL

    完善开发的管理

    完善代码审核、测试机制,软件开发是艺术!

    检测SQL查询的效率

    语法【对IOTimeSQL执行进行统计】:

    SET STATISTICS IO ON

    SET STATISTICS TIME ON

    ------------SQL代码---------

    SET STATISTICS IO OFF

    SET STATISTICS TIME OFF

    注意:在检测之前要清理缓存,因为当我们执行SQL语句的时候查出的数据会在数据库中进行缓存,重新查询会返回缓存中的信息。

    DBCC DROPCLEANBUFFERS

    DBCC FREEPROCCACHE

    经验:使用子查询嵌套不要过多,尽量使用表连接查询代替子查询,因为表连接查询效率稍高一点。

    SQL优化工具

    使用报表服务

    通过Reporting Service查找低效SQL

    选择

    性能 - 批处理执行统计信息和性能相关的几个报表服务:

    性能 - 对象执行统计信息

    性能 - 按平均CPU时间排在前面的查询

    性能 - 按平均IO次数排在前面的查询

    性能 - 按总CPU时间排在前面的查询

    性能 - IO总次数排在前面的查询

    操作示范:

    1.数据引擎上点击右键报表标准报表关心的方面

    clip_image006

    出现如下图:

    clip_image008

    clip_image010

    说明:通过这个报表找到排在前10 sql语句,如果这些语句是用户编写的sql语句,我可以对其进行优化。

    我们可以根据这些信息筛选出需要优化的SQL语句进行优化

    SQL优化经验

    n大表缺索引---必要字段上建立索引

    n索引碎片--维护阶段定期检测索引是否有碎片,如果过多就要对索引重新组织和重建

    n索引失效或者没有使用索引,例如:

    uor语句使用了没有索引的字段

    u对有索引的字段进行了某些函数操作

    避免对索引字段进行数值操作

    示例:

    SELECT * FROM TRAINEE WHERE TraineeNo+10 < 10000 --TraineeNo是索引字段

    执行效果:表'Trainee'扫描计数1,逻辑读取189次,物理读取0次,预读0

    修改后:

    SELECT * FROM TRAINEE WHERE TraineeNo< 10000-10

    执行效果:表'Trainee'扫描计数1,逻辑读取3次,物理读取0次,预读0

    使用Top语句限制返回的数据集

    SELECT ID,TITLE,UNITPRICE FROM BOOKS WHERE AUTHOR = '马骏 主编' --数据库会扫描整个Books表的数据

    修改为:

    SELECT TOP 1 ID,TITLE,UNITPRICE FROM BOOKS WHERE AUTHOR = '马骏 主编' --数据库只要找到一条符合条件的结果就立即返回了。

    n由于返回的数据量减少,IO性能提高了

    n前提:必须知道要返回的行数

    select字段需要多少提取多少

    n按需检索字段,少使用Select *

    u使用*,返回了很多不需要的字段,增加IO负担。

    u使用*,由于没有明确指定要查询那些字段数据,数据库引擎要花费一定时间检索系统表,通过系统表[sysobjectssyscolumns]查询*代表那些字段

    norder by 后跟的字段尽量是索引字段,如果这个字段不是索引字段可以考虑时候可以给这个排序字段加上索引

    使用存储过程优化

    复杂的业务逻辑可以使用存储过程来实现

    优点:

    减少网络流量--将多种操作放在一个过程中,减少访问次数

    速度快--执行是,数据库无需再次编译

    适应性强--可以被多种应用程序调用

     

    执行计划

    什么是执行计划?

    执行计划可以理解为SQL语句的执行路径,通过图表的方式查看SQL的执行步骤

    并不需要SQL语句真正执行,是优化器估算的计算

    来自数据库的统计信息,统计信息月准确,执行计划月精确

    clip_image012

    说明:网络经验:后者效率高于前者,但是以上两个查询语句的性能通过查询计划可以看出其实是一样的,后者不比前者性能好。可能是SQLServer的后期版本进行了优化。

    示例二:

    clip_image014

    clip_image016

    clip_image018

    网络经验:网络经验:三个效率是不一样的,但是我们发现经过SQLServer优化后性能一样。但我们并不能以此推翻前人经验。

    执行计划总结

    主要图表

    clip_image020

    检索表的所有行,当查询没有使用到索引时,查询所采用的形势即为表扫描

    clip_image022

    排序运算符可以读所有传入的行进行排序

    clip_image024

    扫描查询计划的列中指定的聚集索引

    clip_image026

    利用索引的查找功能从聚集索引中检索行

    clip_image028

    执行多表联接逻辑操作,嵌套循环联接通常使用索引在内部表中搜索外部表的每一行

    clip_image030

    从列中指定的非聚集索引中扫描所有行

    clip_image032

    利用索引的查找功能从非聚集索引中检索行

    扫描和查找

    聚集索引有扫描和查找

    非聚集索引也有扫描和查找

    它们的区别:

    扫描:可以理解为对数据进行顺序访问,并未使用索引进行查找

    查找:可以理解为用索引进行查找

    因此查找效率高于索引扫描效率

    执行计划的意义

    对于我们开发高质量SQL是很有帮助的

    首先可以帮助我们查看SQL语句是否利用到索引,比如很复杂的SQL语句中有些用到索引,但是执行计划中却没有索引查找,我们就可以分析相应的原因

    然后我们可以对比不同的执行计划,比如达到同样效果,两个开发人员编写的不同SQL语句谁的效率更高我们就可以对比它们的执行计划来分析。执行计划比较复杂的SQL语句质量就不是很高

    我们还可以结合时间统计【set statistics TIME ON..】一起使用,通过和时间统计结合使用可以更好地发挥执行计划的作用

    有了执行计划和执行时间我们就很容易判断一条SQL语句执行效率高不高

  • 相关阅读:
    在过滤器中验证接口中的Token
    导出EXCEL的 两个方法
    调用webservice接口,返回xml(String)转义
    时间类的操作
    jvm 内存解析以及jvm调优
    redis springMVC 配置与应用
    题目2 成绩排序
    题目1 排序
    题目1042:Coincidence
    题目1131:合唱队形
  • 原文地址:https://www.cnblogs.com/liyuxin/p/2464665.html
Copyright © 2020-2023  润新知