我正在使用azure sql server数据库。我写了一个sql查询来生成reprot。这是:
<input type="text" class="form-control numOnly" onkeypress="return Validate(event);">
<script type="text/javascript">
function Validate(event) {
var regex = new RegExp("^[0-9-!@#$%*?,]");
var key = String.fromCharCode(event.charCode ? event.which : event.charCode);
if (!regex.test(key)) {
event.preventDefault();
return false;
}
}
</script>
有没有办法优化此查询。超时问题来了。我在store过程中编写了这个查询,并使用linq实体框架调用该存储过程。
早些时候我使用了连接,但它更慢,所以尝试使用子查询。工作超过一年现在没有工作。
答案 0 :(得分:1)
这肯定会提高性能,特别是如果表Approval.OrderDetail很大:
...WHERE not exists
(SELECT 1 from Approval.OrderDetail od WHERE od.ProjectID = cte.ProjectID)
答案 1 :(得分:1)
为每个字段编写一个子选择是一种检索数据的可怕方法,因为您可能最终会遇到大量的循环连接,这些连接在大型数据集上的性能很差。
您的原始JOIN
方法是可行的方法,但您需要确保在加入列上有适当的索引。
您还可以使用WHERE
和LEFT JOIN
组合替换IS NULL
子句
LEFT JOIN Approval.OrderDetail od
ON od.ProjectID = p.ProjectID
...
AND od.ProjectID IS NULL;
或NOT EXISTS
(尽管对于主查询返回的每一行,更可能需要扫描更广泛的行)。
WHERE NOT EXISTS
(SELECT 1 FROM Approval.OrderDetail od WHERE od.ProjectID = cte.ProjectID)
在任何一种情况下,请确保您的Project表已在(IsBackgroundUsed, s7ImageGenerated, SiteCode, CreatedDate)
上正确编入索引,并且所有联接都已正确编入索引。
我还质疑您是否确实需要将CreatedDateUTC
字段投放到DATE
类型?
可能的简化可能是:
SELECT
p.ProjectID,
p.CreatedDateUTC,
b.BackgroundName,
pr.Name,
IIF(p.LicenseID IS NULL, 'Standard', l.LicenseName) AS CLA,
pb.PurchaseFG,
pr.FGCode AS ProductFGCode,
'' AS ERPOrderNumber,
0 AS DesignQuantity
FROM Project p
LEFT JOIN Approval.OrderDetail od
ON od.ProjectID = p.ProjectID
LEFT JOIN Background b
ON b.BackgroundID = p.BackgroundID
LEFT JOIN Product pr
ON pr.ProductID = p.ProductID
LEFT JOIN License l
ON l.LicenseID = p.LicenseID
LEFT JOIN Product_Background pb
ON pb.BackgroundID = p.BackgroundID
AND pb.ProductID = p.ProductID
WHERE p.CreatedDateUTC >= @StartDate AND p.CreatedDateUTC <= @EndDate
AND p.IsBackgroundUsed = 1
AND p.s7ImageGenerated = 1
AND p.SiteCode = 'b2c'
AND od.ProjectID IS NULL;
答案 2 :(得分:0)
WHERE CAST(p.CreatedDateUTC AS DATE) >= @StartDate and CAST(p.CreatedDateUTC AS DATE) <= @EndDate
制作此SARGAble,在CreatedDateUTC上创建非聚集索引
假设这是参数,
declare @StartDate datetime='2018-02-01'
declare @EndDate datetime='2018-02-28'
然后,
set @EndDate=dateadd(second,-1,dateadd(day,1,@EndDate))
现在你可以安全地使用这个,
WHERE p.CreatedDateUTC >= @StartDate and p.CreatedDateUTC <= @EndDate
我认为,@ Mark Sinkinson查询将比子查询更好。(我将尝试NOT EXISTS
子句一次)
如果可能,请使用INNER JOIN。 希望您使用存储过程并调用SP。
在所有连接列上创建索引。
由于你的子查询在没有TOP 1的情况下工作正常,所以看起来所有表都与Project有一对一的关系。
CREATE NONCLUSTERED INDEX IX_Project ON project (
CreatedDateUTC
,IsBackgroundUsed
,s7ImageGenerated
,SiteCode
) include (ProductID,LicenseID,BackgroundID);
希望projectID已经是Clustered Index。
答案 3 :(得分:0)
可能不会更快,但更容易为我阅读。
您应该能够调整@StartDate和@EndDate,而不必投射到目前为止。
拥有所有联接的索引和条件。
如果这些是FK,你应该能够使用内连接(并且应该)。
SELECT P.ProjectID , P.CreatedDateUTC,
b.BackgroundName,
pr.Name AS ProductName,
isnull(l.LicenseName, 'Standard') as CLA,
pb.PurchaseFG,
pr.FGcode AS ProductFGCode,
'' AS ERPOrderNumber,
0 AS DesignQuanity
from Project p
left join Background b
on b.BackgroundID = p.BackgroundID
left join Product pr
on pr.ProductID = p.ProductID
left join License l
on l.LicenseID = p.LicenseID
left join Product_background pb
on pb.BackgroundID = p.BackgroundID
and pb.ProductId = p.productID
left join Product pr
on pr.ProductID = p.ProductID
WHERE CAST(p.CreatedDateUTC AS DATE) >= @StartDate
and CAST(p.CreatedDateUTC AS DATE) <= @EndDate
and p.IsBackgroundUsed = 1
and p.s7ImageGenerated = 1
and p.SiteCode = 'b2c'
and not exists (SELECT 1
from Approval.OrderDetail od
WHERE od.ProjectID = p.ProjectID)