[英]How do I optimize my Sql query when calling form ASP .NET Windows for Application?
There are many sub query's in my query.我的查询中有很多子查询。 When I execute the query in Sql Server Management studio it doesn't take much time.
当我在 Sql Server Management Studio 中执行查询时,它不会花费太多时间。 But when I call this query in my ASP .NET Windows for Application then I get the following error.
但是当我在我的 ASP .NET Windows for Application 中调用这个查询时,我得到以下错误。
System.Data.SqlClient.SqlException: 'Execution Timeout Expired.
System.Data.SqlClient.SqlException: '执行超时已过期。 The timeout period elapsed prior to completion of the operation or the server is not responding.'
操作完成之前超时时间已过或服务器没有响应。
My query is:我的查询是:
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
Sql Server Execution SqlServer 执行
My Cs file in Windows Application is:我在 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();
}
}
}
you can set a timeout in your connection but i think its in your join that causing much delay.. can you provide the table structure of those joins?你可以在你的连接中设置一个超时,但我认为它在你的连接中会导致很多延迟..你能提供这些连接的表结构吗?
and create a function instead of case并创建一个函数而不是 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
and in your query并在您的查询中
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
Note that I think you can simplify the CASE expressions greatly by making them into one CASE expression only eg,请注意,我认为您可以通过将它们变成一个 CASE 表达式来大大简化 CASE 表达式,例如,
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;
You could also put it into a new table eg, Nametitle, with NametitleID and the actual NameTitle_short_text (for example) - and then using it in a LEFT JOIN or similar.您还可以将它放入一个新表中,例如 Nametitle,带有 NametitleID 和实际的 NameTitle_short_text(例如) - 然后在 LEFT JOIN 或类似的情况下使用它。
However, the above may not speed up your processing.但是,上述内容可能不会加快您的处理速度。 It gives SQL Server a better shot at guessing what will happen, but it will all still be in-memory processing anyway.
它使 SQL Server 可以更好地猜测会发生什么,但无论如何它仍然会在内存中处理。
For performance, however, I do suggest, a non-clustered index on dbo.EmployeeNames
eg,但是,对于性能,我建议在
dbo.EmployeeNames
上使用非聚集索引,例如,
CREATE NONCLUSTERED INDEX IX_EmployeeNames_DataType ON dbo.EmployeeNames
(DataTypeID, EmployeeDataId, Name);
This index will help with the 4 lookups you need to do - instead of reading the whole names table, it can seek to relevant spots.该索引将帮助您进行 4 次查找 - 而不是读取整个名称表,它可以查找相关位置。
Note that for small reads (eg, one or a few IDs) this will perform similarly or perhaps slightly worse than an index with the key columns the other way around eg, EmployeeDataId, DataTypeID, Name
.请注意,对于小的读取(例如,一个或几个 ID),这将与具有相反方向的键列(例如
EmployeeDataId, DataTypeID, Name
的索引的性能相似或可能略差。 However, I believe for larger result sets, this will give a better results.但是,我相信对于更大的结果集,这会给出更好的结果。
It may be worth testing in your specific circumstances (note though, I'm guessing the Primary Key/clustered index for EmployeeNames is the second option above; if so then adding the same as a non-clustered index won't help).在您的特定情况下可能值得测试(但请注意,我猜测 EmployeeNames 的主键/聚集索引是上面的第二个选项;如果是这样,那么添加与非聚集索引相同的索引将无济于事)。
Finally - note that your application/query has no WHERE clause - so you are getting all the data from these tables.最后 - 请注意,您的应用程序/查询没有 WHERE 子句 - 因此您将从这些表中获取所有数据。
Is getting all the rows what you want?得到所有你想要的行吗? Or do you only want one (or a handful) of rows?
或者你只想要一排(或几排)? If you can reduce the rows required, it will typically speed up processing by a large factor.
如果您可以减少所需的行数,通常会大大加快处理速度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.