我有2个表来自合并以下表:
Authors
-Aid bigint
-Surname nvarchar(500)
-Email nvarchar(500)
Articles
-ArId varchar(50)
-Year int
-……Some other fields……
ArticleAuthors
-ArId varchar(50)
-Aid bigint
Classifications
-ClassNumber int
-ClassDescription nvarchar(100)
ClassArticles
-ArId varchar(50)
-ClassNumber int
对这些表进行非规范化后,得到的表格为:
Articles
-FieldId int
-ArId varchar(50)
-ClassNumber int (Foreign key from the Classifications table)
-Year int
Authors
-FieldId int
-ArId varchar(50) (Foreign key from the Articles table)
-Aid bigint
-Surname nvarchar(500)
-Email nvarchar(500)
-Year int
以下是结果表中数据的条件:
问题是:
我们需要创建一个存储过程,在以下条件下从两个表[Aid,Surname,Email]获取以下结果:
在特定年份(AND)期间和之后撰写文章的作者
我们需要查询花费最少的时间
如果有人可以提供帮助,非常感谢。
答案 0 :(得分:2)
如果没有这些数据,这很难处理,但我创建了表格并复制了程序,以便大致了解查询计划和潜在问题。
第一个值得注意的事情,查询的部分写成:
SELECT DISTINCT Aid
FROM Authors EAE
WHERE EAE.[Year] >= @year AND EAE.Email IS NOT NULL AND EAE.Email != ' '
要进行表扫描,您将Year作为分区键,但在每个分区中,没有索引支持查询中的email子句。作为旁注,EAE.Email!=''可能不会给你很满意的期望。 如果''!=''print'true',则打印'false' 这对大多数系统都是错误的。 (基于ansi填充)
FROM Articles ED
INNER JOIN Authors EAD ON EAD.ArId = ED.ArId
WHERE EAD.Aid = [YearAuthors].Aid AND ED.ClassNumber = @classNumber
ED.ClassNumber没有支持索引,导致聚簇索引扫描。
在最终的选择声明中: INNER JOIN作者EA ON EA.Aid =#TT.Aid
#TT方面没有支持索引,在作者表一侧似乎没有。
WHERE EA.Email IS NOT NULL AND EA.Email != ' '
这没有支持索引,导致扫描。
还有很多问题,有大量的问题可能会随着合适的索引而消失 - 你必须在表格上找出一些基本的索引,然后得到一个新的查询计划/集合问题并反复修复计划 - 你不会在一个'银弹'镜头中修复它。
答案 1 :(得分:1)
您是否需要帮助编写查询,或帮助修复性能?查询本身应该相对简单。这不是你要获得最大收益的地方。
SQL Server通过调整索引自带tools for analyzing queries and boosting performance。这就是你要看到帮助它快速运行的最大帮助。
答案 2 :(得分:0)
第一步是适当的索引。使用where标准作为主要竞争者,然后在未在选址中使用的项目可以简单地包含在索引中。如上所述,有标准工具和查询可以找到这些。
要专注于查询,请运行查询并启用“查询| 包含执行计划”(Ctrl + M)。这应该显示出任何明显的瓶颈。
答案 3 :(得分:0)
考虑到前面提到的条件 这是我创建的查询,但需要3分钟(网页响应的时间很长):
CREATE PROC [dbo].[GetAuthorForMailing]
(
@classNumber INT,
@noPapers int,
@year int,
@percent int
)
AS
BEGIN
CREATE TABLE #TT
(
Aid bigint,
allPapers int,
classPapers int,
perc as CEILING(CAST(classPapers AS DECIMAL) / CAST(allPapers AS DECIMAL) * 100)
)
INSERT INTO #TT(Aid,allPapers,classPapers)
SELECT [YearAuthors].Aid,
(
SELECT COUNT(EA.Aid)
FROM Authors EA
WHERE EA.Aid =[YearAuthors].Aid) AS [AllPapers],
(
SELECT COUNT(*)
FROM Articles ED INNER JOIN Authors EAD ON EAD.ArId = ED.ArId
WHERE EAD.Aid = [YearAuthors].Aid AND ED.ClassNumber = @classNumber) AS [ClassPapers]
FROM
(
SELECT DISTINCT Aid
FROM Authors EAE
WHERE EAE.[Year] >= @year AND EAE.Email IS NOT NULL AND EAE.Email != ' '
)AS [YearAuthors]
SELECT DISTINCT EA.Aid,EA.Surname,EA.Email,[Year]
FROM #TT INNER JOIN Authors EA ON EA.Aid = #TT.Aid
AND allPapers > @noPapers
AND perc > @percent
AND EA.[Year] = (SELECT MAX([Year]) FROM Authors WHERE Aid = EA.Aid)
WHERE EA.Email IS NOT NULL AND EA.Email != ' '
DROP TABLE #TT