我遇到了一个问题,即通过用硬值替换参数,我的SQL Server查询性能显着提高。例如:
SELECT * FROM Table1 WHERE RowNumber >= 101 AND ID < 200
明显快于以下情况:
DECLARE @Start int = 101;
DECLARE @End Start int = 200;
SELECT * FROM Table1 WHERE RowNumber >= @Start AND RowNumber < @End
第一个在大约2s运行,第二个在15s运行。所以我的问题是,如果它们是数字和pnly参数化字符串,我可以安全地使用硬值吗?我不相信这是索引的问题,因为RowNumber列已经被索引为非聚集索引。我并不熟悉所有的SQL注入技术,但是我多年来一直在使用所有输入值的参数来试图避免SQL注入攻击。我从未意识到通过使用参数可能会降低性能。
我还看到了一些关于使用参数降低性能的问题,但我还没有看到关于如何解决问题的明确答案。
答案 0 :(得分:3)
无论如何,我都会说,鉴于这句话“我对所有SQL注入技术并不熟悉”,那么你应该始终保证安全并继续参数化查询。
我在用户组上讨论SQL注入攻击,我不认为我知道一切。我以为我知道了很多,并且可以通过各种方式进行攻击,但是我甚至有一个人在谈话之后来找我并告诉我他在一个公司发生的攻击事件, OCR机器读取的纸质表单。我以前从未考虑过这种形式的攻击。</ p>
攻击以各种奇怪的方式发生,即使你已经想到了所有可能的事情,其他人总会想到其他一些攻击系统的方法。
答案 1 :(得分:0)
SQL Server会尽早评估一些常量表达式,以提高查询性能。这被称为常数折叠。
在上面的查询中,与编译查询之前一样,将评估常量,并且优化器不需要执行任何操作。但是在参数的情况下,优化器必须在每次运行时编译它。
答案 2 :(得分:0)
数字字段很危险,因为评论( // 或 / )和空格用于进行SQL注入(攻击)
如果用户和密码匹配,许多网站都允许用户进入保留区域。
假设一个使用数字字段作为密码的疯狂网站:
..... Where User='James' and Pass=123
即使在Javascript中验证用户输入,也可以很容易地更改帖子值: 因此,可以“注入”下面的部分而不是123
123 or 1=1
返回所有记录。许多站点检测到这种情况,但是用户字段是“用户”或“用户名”是很常见的。因此,可以在结构中尝试“用户”和其他常见字段名称
12 or 1=1 and User='James'
在这种情况下,只会返回所需的记录!
数字字段的简单解决方案是使用单引号:
Select User='James' and Pass='123'
我已经验证了SQL Server,MySQL和SQLite接受这种语法,可能会有轻微的过度收费。由于电子邮件,名称等原因,避免在字符串中使用单引号会更难。