Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
预定义查询是否比使用ADO.NET的即席SQL查询更高效?_Sql_Sql Server_Ado.net_Sqldatareader_Datareader - Fatal编程技术网

预定义查询是否比使用ADO.NET的即席SQL查询更高效?

预定义查询是否比使用ADO.NET的即席SQL查询更高效?,sql,sql-server,ado.net,sqldatareader,datareader,Sql,Sql Server,Ado.net,Sqldatareader,Datareader,我们有一个表cropedimage,它有Id,PosX,PosY,Width,Heigth列,数据类型为tinyint,另一列cropedpicture,数据类型为varbinary 这是一种特别的方式: List<int> GetList = GetTopNecessaryImages(); for(int i = 0; i < 100; i++){ com.CommandText = "select * from CroppedImage where Id=" +

我们有一个表
cropedimage
,它有
Id
PosX
PosY
Width
Heigth
列,数据类型为
tinyint
,另一列
cropedpicture
,数据类型为
varbinary

这是一种特别的方式:

List<int> GetList = GetTopNecessaryImages();
for(int i = 0; i < 100; i++){
    com.CommandText = "select * from CroppedImage where Id=" + GetList[i];
    using (SqlDataReader objSqlDtReader = com.ExecuteReader()) 
    {
        while(objSqlDtReader.Read()) 
        {
             CropImage objCrop = new CropImage ();
             CropImage.Img = (objSqlDtReader["CroppedPicture"]);
        }
    }
}
List GetList=getTopnecessaryImage();
对于(int i=0;i<100;i++){
com.CommandText=“从裁剪图像中选择*,其中Id=“+GetList[i];
使用(SqlDataReader objsqldtereader=com.ExecuteReader())
{
while(objSqlDtReader.Read())
{
CropImage objCrop=新CropImage();
Img=(objSqlDtReader[“cropedpicture”]);
}
}
}
这里是带有参数的预定义查询

List<int> GetList = GetTopNecessaryImages();
for(int i = 0; i < 100; i++){
    com.CommandText = "select * from CroppedImage where Id=@IdPar";
    com.Parameters.AddWithValue("@IdPar", GetList[i]);
    using (SqlDataReader objSqlDtReader = com.ExecuteReader()) 
    {
        while(objSqlDtReader.Read()) 
        {
             CropImage objCrop = new CropImage (); 
             CropImage.Img = (objSqlDtReader["CroppedPicture"]);
        }
    }
}
List GetList=getTopnecessaryImage();
对于(int i=0;i<100;i++){
com.CommandText=“从裁剪图像中选择*,其中Id=@IdPar”;
AddWithValue(“@IdPar”,GetList[i]);
使用(SqlDataReader objsqldtereader=com.ExecuteReader())
{
while(objSqlDtReader.Read())
{
CropImage objCrop=新CropImage();
Img=(objSqlDtReader[“cropedpicture”]);
}
}
}
图像
字段小于250KB。 我已经测试了这两种查询,在我的机器上没有发现任何差异,但是数据库管理员告诉我,临时查询比承载SQL的服务器上预定义的查询占用更多内存。
这是真的吗?这两个选项在性能上有什么不同吗?

事实上,您的DBA是不正确的。这些都是临时查询。即席查询得到为它们创建的执行计划,它们被缓存,就像存储过程的执行计划一样。首选第二种方法,因为您正在使用参数化查询并阻止sql注入。但我看到的是,您正在使用AddWithValue。这应该避免,因为它有时会出错

实际上,您的DBA是正确的,尽管术语有点混乱。这更多的是参数化查询与非参数化查询的问题

对于参数化查询(
“从cropeImage中选择*,其中Id=@IdPar”
),即使使用不同的参数多次执行此查询,SQL Server也只需对查询进行一次分析和编译。查询的任何后续执行都将重用缓存中的相同查询计划

相反,每次使用不同的
GetList[i]
值执行非参数化查询(
“从裁剪图像中选择*”,其中Id=“+GetList[i]
)时,它将被视为完全不同的查询。在这种情况下,每次都会在SQL Server上解析和重新编译查询。这将消耗更多内存,因为数据库服务器现在必须缓存多个查询计划,而不是单个查询计划

对于少量查询,差异不会明显。但一旦事务量很大,您就可能开始注意到对速度和内存的影响


下面是一篇有趣的文章,它提供了关于这一问题的更多细节:。

事实上,您的DBA是不正确的。这些都是临时查询。即席查询得到为它们创建的执行计划,它们被缓存,就像存储过程的执行计划一样。首选第二种方法,因为您正在使用参数化查询并阻止sql注入。但我看到的是,您正在使用AddWithValue。这应该避免,因为它有时会出错。DBA的意思可能是,不必编译“预定义”(=预编译)视图(或存储过程或表值函数)。但是这样一个简单的查询在任何情况下都是快速的。。。(至少如果在“Id”;-)上有一个索引),即使您的DBA意味着存储过程或视图,但这并不意味着它会神奇地更快。它们都可以归结为创建(或重用,如果有的话)一个执行计划。正如您所说的,这些图像很小,您可以一次选择一个。对于发送的250k图像,几乎没有ram消耗。一旦查询执行,sql server就会将其丢弃。老实说,我认为最大的问题是你做这个过程RBAR。您应该一次获取所有需要的数据,而不是反复查询。这将大大减轻sql盒的压力。