我有一个查询,我正在C#中执行,这花费了太多时间:
string Query = "SELECT COUNT(HISTORYID) FROM HISTORY WHERE YEAR(CREATEDATE) = YEAR(GETDATE()) ";
Query += "AND MONTH(CREATEDATE) = MONTH(GETDATE()) AND DAY(CREATEDATE) = DAY(GETDATE()) AND USERID = '" + EmployeeID + "' ";
Query += "AND TYPE = '5'";
然后我使用SqlCommand Command = new SqlCommand(Query,Connection)和SqlDataReader Reader = Command.ExecuteReader()来读入数据。这需要一分钟才能从C#执行,但在SSMS中要快得多。
我从谷歌搜索中看到你可以用CompiledQuery做一些事情,但我很困惑我是否仍然可以使用内置的SQL函数YEAR,MONTH,DAY和GETDATE。
如果有人能告诉我如何使用内置函数创建和调用编译查询的示例,我将非常感激!提前谢谢。
答案 0 :(得分:3)
不幸的是,编译的查询对你没有帮助:编译时间可能不是一分钟的重要部分。我假设您已经有一个包含部分或全部(createdate, userid, type)
的索引。如果没有,请添加索引。
可能的问题是您使用函数将阻止使用创建的任何索引,从而导致索引扫描或表扫描速度慢。重写您的查询以改为使用BETWEEN,它应该能够使用索引。这将使它更快。
此外,在查询中使用EXPLAIN来查看它正在使用哪些索引(如果有)。在这里发布这些信息。
答案 1 :(得分:2)
Linq to Sql不是解决查询所有性能问题的神奇工具。实际上它会产生类似的查询。而是分析您的查询以找出它的缓慢位置,并通过调整查询和/或调整索引来修复这些问题。
此外,我必须指出这样做是不好的做法:
AND USERID = '" + EmployeeID + "' "
而是尝试使用参数化查询。这意味着您使用:
AND USERID=@UserId
然后,在执行命令之前设置该参数(假设NVARCHAR(255),调整为需要):
commmand.Parameters.Add("@UserId", SqlDbType.NVarChar, 255).Value = EmployeeID;
答案 2 :(得分:2)
即使您在CREATEDATE上有索引,它也不会使用它。您需要将日期逻辑更改为GETDATE()日期时间到以下日期:
WHERE CREATEDATE>=DATEADD(day,DATEDIFF(day,0,GETDATE()),0)
AND CREATEDATE<DATEADD(day,DATEDIFF(day,0,GETDATE()),0)+1 ...
在列上使用该函数时,例如:YEAR(CREATEDATE)
,可以防止使用索引。