Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.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
C# 在为应用程序调用表单ASP.NET Windows时,如何优化Sql查询?_C#_Sql_Sql Server - Fatal编程技术网

C# 在为应用程序调用表单ASP.NET Windows时,如何优化Sql查询?

C# 在为应用程序调用表单ASP.NET Windows时,如何优化Sql查询?,c#,sql,sql-server,C#,Sql,Sql Server,我的查询中有许多子查询。当我在SQLServerManagementStudio中执行查询时,不会花费太多时间。但是,当我在ASP.NET Windows for应用程序中调用此查询时,会出现以下错误 System.Data.SqlClient.SqlException:'执行超时已过期。这个 在完成操作之前经过的超时时间或 服务器没有响应。' 我的问题是: SELECT id.Id, id.CardNo, (CASE WHEN id.NameTitle = 0 THEN '

我的查询中有许多子查询。当我在SQLServerManagementStudio中执行查询时,不会花费太多时间。但是,当我在ASP.NET Windows for应用程序中调用此查询时,会出现以下错误

System.Data.SqlClient.SqlException:'执行超时已过期。这个 在完成操作之前经过的超时时间或 服务器没有响应。'

我的问题是:

SELECT
  id.Id,
  id.CardNo,
  (CASE
    WHEN id.NameTitle = 0 THEN ''
    ELSE CASE
        WHEN id.NameTitle = 1 THEN 'Mr. '
        ELSE CASE
            WHEN id.NameTitle = 2 THEN 'Mrs. '
            ELSE CASE
                WHEN id.NameTitle
                  = 3 THEN 'Md. '
                ELSE CASE
                    WHEN id.NameTitle = 4 THEN 'Engr. '
                    ELSE CASE
                        WHEN id.NameTitle = 5 THEN 'Dr. '
                        ELSE CASE
                            WHEN id.NameTitle = 6 THEN 'Mosa. '
                            ELSE CASE
                                WHEN id.NameTitle = 7 THEN 'Shree. '
                                ELSE CASE
                                    WHEN id.NameTitle = 8 THEN 'Mst. '
                                    ELSE CASE
                                        WHEN id.NameTitle = 9 THEN 'Miss. '
                                        ELSE ''
                                      END
                                  END
                              END
                          END
                      END
                  END
              END
          END
      END
  END) + (firstName.[Name] + ' ' + secondName.Name + ' ' + thirdName.Name + ' ' + fourthame.Name) AS Name
FROM dbo.EmployeeDatas id
JOIN dbo.EmployeeNames firstName
  ON id.Id = firstName.EmployeeDataId
JOIN dbo.EmployeeNames secondName
  ON id.Id = secondName.EmployeeDataId
JOIN dbo.EmployeeNames thirdName
  ON id.Id = thirdName.EmployeeDataId
JOIN dbo.EmployeeNames fourthame
  ON id.Id = fourthame.EmployeeDataId
WHERE firstName.DataTypeId = 1
AND secondName.DataTypeId = 2
AND thirdName.DataTypeId = 3
AND fourthame.DataTypeId = 4

Windows应用程序中的我的Cs文件是:

namespace SnowtexBiometricExe.Forms
{
    public partial class frmRegistration : Form
    {
        public frmRegistration()
        {
            InitializeComponent();
        }
        private void FrmRegistration_Load(object sender, EventArgs e)
        {
            string mainConn = ConfigurationManager.ConnectionStrings["SBR"].ConnectionString;
            SqlConnection connection = new SqlConnection(mainConn);
            string query = "select id.Id, id.CardNo, (CASE WHEN id.NameTitle = 0 THEN '' ELSE CASE WHEN id.NameTitle = 1 THEN 'Mr. ' ELSE CASE WHEN id.NameTitle = 2 THEN 'Mrs. ' ELSE CASE WHEN id.NameTitle = 3 THEN 'Md. ' ELSE CASE WHEN id.NameTitle = 4 THEN 'Engr. ' ELSE CASE WHEN id.NameTitle = 5 THEN 'Dr. ' ELSE CASE WHEN id.NameTitle = 6 THEN 'Mosa. ' ELSE CASE WHEN id.NameTitle = 7 THEN 'Shree. ' ELSE CASE WHEN id.NameTitle = 8 THEN 'Mst. ' ELSE CASE WHEN id.NameTitle = 9 THEN 'Miss. ' ELSE '' END END END END END END END END END END) +(firstName.[Name] + ' ' + secondName.Name + ' ' + thirdName.Name + ' ' + fourthame.Name) AS Name  from dbo.EmployeeDatas id join dbo.EmployeeNames firstName on id.Id = firstName.EmployeeDataId join dbo.EmployeeNames secondName on id.Id = secondName.EmployeeDataId join dbo.EmployeeNames thirdName on id.Id = thirdName.EmployeeDataId join dbo.EmployeeNames fourthame on id.Id = fourthame.EmployeeDataId where firstName.DataTypeId = 1 and secondName.DataTypeId = 2 and thirdName.DataTypeId = 3 and fourthame.DataTypeId = 4";
            SqlCommand cmd = new SqlCommand(query, connection);
            connection.Open();
            SqlDataAdapter sda = new SqlDataAdapter(cmd);
            DataTable dataTable = new DataTable();
            sda.Fill(dataTable);
            lstEmployee.DisplayMember = "Name";
            lstEmployee.DataSource = dataTable;
            connection.Close();
        }        
    }
}

您可以在连接中设置超时,但我认为是在您的连接中造成了很大的延迟。。 您能提供这些联接的表结构吗

并创建一个函数而不是case

CREATE FUNCTION setTitle
(
@title int,
@firstname varchar(20),
@secondname varchar(20),
@thirdname varchar(20),
@fourthname varchar(20)
)
returns varchar(50)
as
begin
declare @myTitle as varchar(10);
declare @Name as varchar(50)
if(@title = 0)
set @myTitle = '';

else if(@title = 1)
set @myTitle = 'Mr.';

else if(@title = 2)
set @myTitle = 'Mrs.';

else if(@title = 3)
set @myTitle = 'Md.';

else if(@title = 4)
set @myTitle = 'Engr.';

else if(@title = 5)
set @myTitle = 'Dr.';

else if(@title = 6)
set @myTitle = 'Mosa.';

else if(@title = 7)
set @myTitle = 'Shree.';

else if(@title = 8)
set @myTitle = 'Mst.';

else if(@title = 9)
set @myTitle = 'Miss.';

select @Name = @myTitle + ' ' + @firstname + ' ' + @secondname  + ' ' + @thirdname + ' 
' + @fourthname 

return @Name
end
在你的询问中

SELECT
id.Id,
id.CardNo,
dbo.setTitle(id.NameTitle,firstName. 
[Name],secondName.Name,thirdName.Name,fourthame.Name) AS Name
FROM dbo.EmployeeDatas id
JOIN dbo.EmployeeNames firstName
ON id.Id = firstName.EmployeeDataId
JOIN dbo.EmployeeNames secondName
ON id.Id = secondName.EmployeeDataId
JOIN dbo.EmployeeNames thirdName
ON id.Id = thirdName.EmployeeDataId
JOIN dbo.EmployeeNames fourthame
ON id.Id = fourthame.EmployeeDataId
WHERE firstName.DataTypeId = 1
AND secondName.DataTypeId = 2
AND thirdName.DataTypeId = 3
AND fourthame.DataTypeId = 4

请注意,我认为您可以将大小写表达式简化为一个大小写表达式,从而大大简化大小写表达式,例如

SELECT
  id.Id,
  id.CardNo,
  (CASE id.NameTitle
      WHEN 0 THEN ''
      WHEN 1 THEN 'Mr. '
      WHEN 2 THEN 'Mrs. '
      WHEN 3 THEN 'Md. '
      WHEN 4 THEN 'Engr. '
      WHEN 5 THEN 'Dr. '
      WHEN 6 THEN 'Mosa. '
      WHEN 7 THEN 'Shree. '
      WHEN 8 THEN 'Mst. '
      WHEN 9 THEN 'Miss. '
      ELSE '' END)
    + (firstName.[Name] + ' ' + secondName.[Name] + ' ' + thirdName.[Name] + ' ' + fourthName.[Name]) AS [Name]
FROM dbo.EmployeeDatas id
    JOIN dbo.EmployeeNames firstName ON id.Id = firstName.EmployeeDataId
    JOIN dbo.EmployeeNames secondName ON id.Id = secondName.EmployeeDataId
    JOIN dbo.EmployeeNames thirdName ON id.Id = thirdName.EmployeeDataId
    JOIN dbo.EmployeeNames fourthName ON id.Id = fourthName.EmployeeDataId
WHERE firstName.DataTypeId = 1
    AND secondName.DataTypeId = 2
    AND thirdName.DataTypeId = 3
    AND fourthName.DataTypeId = 4;
您还可以将它放入一个新表中,例如nametTitle,带有nametTitleId和实际的nametTitle_short_文本(例如),然后在左联接或类似的情况下使用它

但是,上述情况可能不会加快处理速度。它使SQLServer能够更好地猜测将发生什么,但无论如何,它都将在内存中处理


但是,为了提高性能,我建议在
dbo.EmployeeNames
e、 g

这个索引将有助于您进行4次查找-它可以查找相关点,而不是读取整个名称表

请注意,对于小的读取(例如,一个或几个ID),这将执行类似的或可能稍差于具有键列的索引,反之亦然,例如,
EmployeeDataId、DataTypeID、Name
。然而,我相信对于较大的结果集,这将给出更好的结果

在您的特定情况下,它可能值得测试(不过请注意,我猜EmployeeNames的主键/聚集索引是上面的第二个选项;如果是这样,那么添加相同的索引作为非聚集索引将没有帮助)


最后,请注意,您的应用程序/查询没有WHERE子句,因此您将从这些表中获取所有数据


获取所有行是您想要的吗?或者你只想要一行(或一把)的?如果您可以减少所需的行数,通常会大大加快处理速度。

此查询非常可疑,而且无法维护。。为什么要在内存中执行所有这些嵌套操作,使用名称联接,或者创建一个Db函数来执行这些操作,事实上,我对这种模式非常怀疑,我认为您可以在其他情况下对所有内部联接进行解码并重新写入字符串agg函数。我认为这样会更好,因为您正在减少联接。实际上,我希望所有员工的姓名都显示在下拉列表中。谢谢。案例表达的简化对我很有用。
CREATE NONCLUSTERED INDEX IX_EmployeeNames_DataType ON dbo.EmployeeNames
    (DataTypeID, EmployeeDataId, Name);