我有以下查询,并且它不能完全按照我想要的方式工作,而且它非常慢,所以我想我会请求一些帮助。
CREATE PROCEDURE [dbo].[SummaryReport]
@event varchar(7) = null,
@pet_num varchar(12) = null
AS
BEGIN
WITH pet_counts
AS (SELECT event,
pet_num,
pageid,
linenum,
tot_sig_page,
IDNUM,
val_date,
obj_type
-- Objections
,case when sum(case when INV_SIG = '1' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when INV_SIG = '1' then 1 else 0 end)) + ' Invalid Sig' else '' end as InvalidSignature
,case when sum(case when INV_ADR = '1' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when INV_ADR = '1' then 1 else 0 end)) + ' Invalid Addr' else '' end as InvalidAddress
,case when sum(case when INV_DIST = '1' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when INV_DIST = '1' then 1 else 0 end)) + ' Invalid Dist' else '' end as InvalidDistrict
,case when sum(case when inc_adr = '1' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when inc_adr = '1' then 1 else 0 end)) + ' Inc Add' else '' end as IncAdd
,case when sum(case when dup_sig = '1' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when dup_sig = '1' then 1 else 0 end)) + ' Dup Sig' else '' end as DupSig
,case when sum(case when Inv_Circulator = '1' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when Inv_Circulator = '1' then 1 else 0 end)) + ' No CRC Date' else '' end as NoCRCDate
,case when sum(case when isnull(REASON,'') <> '' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when isnull(REASON,'') <> '' then 1 else 0 end)) + ' Other' else '' end as OtherReason
,sum(case when INV_SIG = '1' then 1 else 0 end)
+ sum(case when INV_ADR = '1' then 1 else 0 end)
+ sum(case when INV_DIST = '1' then 1 else 0 end)
+ sum(case when inc_adr = '1' then 1 else 0 end)
+ sum(case when dup_sig = '1' then 1 else 0 end)
+ sum(case when Inv_Circulator = '1' then 1 else 0 end)
+ sum(case when isnull(REASON,'') <> '' then 1 else 0 end) as TotalObjections
-- Sustained
,case when sum(case when INV_SIG_ST = 'S' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when INV_SIG_ST = 'S' then 1 else 0 end)) + ' Sustained (Invalid Sig)' else '' end as SustainedInvalidSignature
,case when sum(case when INV_ADR_ST = 'S' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when INV_ADR_st = 'S' then 1 else 0 end)) + ' Sustained (Invalid Addr)' else '' end as SustainedInvalidAddress
,case when sum(case when INV_DIST_ST = 'S' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when INV_DIST_st = 'S' then 1 else 0 end)) + ' Sustained (Invalid Dist)' else '' end as SustainedInvalidDistrict
,case when sum(case when inc_adr_ST = 'S' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when inc_adr_st = 'S' then 1 else 0 end)) + ' Sustained (Inc Add)' else '' end as SustainedIncAdd
,case when sum(case when dup_sig_ST = 'S' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when dup_sig_st = 'S' then 1 else 0 end)) + ' Sustained (Dup Sig)' else '' end as SustainedDupSig
,case when sum(case when Inv_Circulator_ST = 'S' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when Inv_Circulator_ST = 'S' then 1 else 0 end)) + ' Sustained (No CRC Date)' else '' end as SustainedNoCRCDate
,case when sum(case when oth_reas_ST = 'S' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when oth_reas_st = 'S' then 1 else 0 end)) + ' Sustained (Other)' else '' end as SustainedOtherReason
,sum(case when INV_SIG_ST = 'S' then 1 else 0 end)
+ sum(case when INV_ADR_ST = 'S' then 1 else 0 end)
+ sum(case when INV_DIST_ST = 'S' then 1 else 0 end)
+ sum(case when inc_adr_ST = 'S' then 1 else 0 end)
+ sum(case when dup_sig_ST = 'S' then 1 else 0 end)
+ sum(case when Inv_Circulator_ST = 'S' then 1 else 0 end)
+ sum(case when oth_reas_ST = 'S' then 1 else 0 end) as TotalSustained
-- Overruled
,case when sum(case when INV_SIG_ST = 'O' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when INV_SIG_ST = 'O' then 1 else 0 end)) + ' Overruled (Invalid Sig)' else '' end as OverruledInvalidSignature
,case when sum(case when INV_ADR_ST = 'O' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when INV_ADR_st = 'O' then 1 else 0 end)) + ' Overruled (Invalid Addr)' else '' end as OverruledInvalidAddress
,case when sum(case when INV_DIST_ST = 'O' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when INV_DIST_st = 'O' then 1 else 0 end)) + ' Overruled (Invalid Dist)' else '' end as OverruledInvalidDistrict
,case when sum(case when inc_adr_ST = 'O' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when inc_adr_st = 'O' then 1 else 0 end)) + ' Overruled (Inc Add)' else '' end as OverruledIncAdd
,case when sum(case when dup_sig_ST = 'O' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when dup_sig_st = 'O' then 1 else 0 end)) + ' Overruled (Dup Sig)' else '' end as OverruledDupSig
,case when sum(case when Inv_Circulator_ST = 'O' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when Inv_Circulator_ST = 'O' then 1 else 0 end)) + ' Overruled (No CRC Date)' else '' end as OverruledNoCRCDate
,case when sum(case when oth_reas_ST = 'O' then 1 else 0 end) > 0 then convert(varchar(5), sum(case when oth_reas_st = 'O' then 1 else 0 end)) + ' Overruled (Other)' else '' end as OverruledOtherReason
,sum(case when INV_SIG_ST = 'O' then 1 else 0 end)
+ sum(case when INV_ADR_ST = 'O' then 1 else 0 end)
+ sum(case when INV_DIST_ST = 'O' then 1 else 0 end)
+ sum(case when inc_adr_ST = 'O' then 1 else 0 end)
+ sum(case when dup_sig_ST = 'O' then 1 else 0 end)
+ sum(case when Inv_Circulator_ST = 'O' then 1 else 0 end)
+ sum(case when oth_reas_ST = 'O' then 1 else 0 end) as TotalOverruled
-- Cand Exceptions
,sum(case when INV_SIG_EX = 'C' then 1 else 0 end)
+ sum(case when INV_ADR_EX = 'C' then 1 else 0 end)
+ sum(case when INV_DIST_EX = 'C' then 1 else 0 end)
+ sum(case when inc_adr_EX = 'C' then 1 else 0 end)
+ sum(case when dup_sig_EX = 'C' then 1 else 0 end)
+ sum(case when Inv_Circulator_EX= 'C' then 1 else 0 end)
+ sum(case when oth_reas_EX = 'C' then 1 else 0 end) as TotalCandidateExceptions
-- Objector Exceptions
,sum(case when INV_SIG_EX = 'O' then 1 else 0 end)
+ sum(case when INV_ADR_EX = 'O' then 1 else 0 end)
+ sum(case when INV_DIST_EX = 'O' then 1 else 0 end)
+ sum(case when inc_adr_EX = 'O' then 1 else 0 end)
+ sum(case when dup_sig_EX = 'O' then 1 else 0 end)
+ sum(case when Inv_Circulator_EX = 'O' then 1 else 0 end)
+ sum(case when oth_reas_EX = 'O' then 1 else 0 end) as TotalObjectorExceptions
FROM petchl
WHERE event=@event
AND pet_num=@pet_num
GROUP BY event,
pet_num,
pageid,
linenum,
tot_sig_page,
IDNUM,
val_date,
obj_type),
user_info as
(
SELECT vp.IDNUM,
v.full_name,
ltrim((isnull(rtrim(ltrim(v.addr_num)),''))
+ ' ' + isnull(rtrim(ltrim(v.addr_frac)),'')
+ ' ' + isnull(rtrim(ltrim(v.addr_dir)),'')
+ ' ' + isnull(rtrim(ltrim(v.addr_str)),'')
+ ' ' + isnull(rtrim(ltrim(v.addr_type)),'')
+ ' ' + isnull(rtrim(ltrim(v.addr_other)),'')) as address1,
(isnull(v.cityname,'')+ ' ' + isnull(v.addr_zip,'')) as address2,
v.regdate,
v.birthdate,
v.sex,
v.prec,
s.signature
FROM petchl AS vp INNER JOIN
v_JPPUsers AS v ON vp.IDNUM = v.IDNUM LEFT OUTER JOIN
Signatures AS s ON v.IDNUM = s.IDNUM
WHERE vp.event=@event
AND vp.pet_num=@pet_num
UNION ALL
SELECT vp.IDNUM,
v.full_name,
ltrim((isnull(rtrim(ltrim(v.addr_num)),''))
+ ' ' + isnull(rtrim(ltrim(v.addr_frac)),'')
+ ' ' + isnull(rtrim(ltrim(v.addr_dir)),'')
+ ' ' + isnull(rtrim(ltrim(v.addr_str)),'')
+ ' ' + isnull(rtrim(ltrim(v.addr_type)),'')
+ ' ' + isnull(rtrim(ltrim(v.addr_other)),'')) as address1,
(isnull(v.cityname,'')+ ' ' + isnull(v.addr_zip,'')) as address2,
null as regdate,
v.birthdate,
v.sex,
v.prec,
s.signature
FROM petchl AS vp INNER JOIN
v_Cityusers AS v ON vp.IDNUM = v.IDNUM LEFT OUTER JOIN
v_CitySignatures AS s ON v.IDNUM = s.IDNUM
WHERE vp.event=@event
AND vp.pet_num=@pet_num
)
SELECT p.event,
p.PET_NUM,
p.PAGEID,
p.LINENUM,
convert(varchar(10), vp.pet_date, 101) as pet_date,
p.InvalidSignature,
p.InvalidAddress,
p.InvalidDistrict,
p.IncAdd,
p.DupSig,
p.NoCRCDate,
p.OtherReason,
p.TotalObjections,
p.SustainedInvalidSignature,
p.SustainedInvalidAddress,
p.SustainedInvalidDistrict,
p.SustainedIncAdd,
p.SustainedDupSig,
p.SustainedNoCRCDate,
p.SustainedOtherReason,
p.TotalSustained,
p.OverruledInvalidSignature,
p.OverruledInvalidAddress,
p.OverruledInvalidDistrict,
p.OverruledIncAdd,
p.OverruledDupSig,
p.OverruledNoCRCDate,
p.OverruledOtherReason,
p.TotalOverruled,
p.TotalCandidateExceptions,
p.TotalObjectorExceptions,
p.TOT_SIG_PAGE,
v.full_name,
v.address1,
v.address2,
p.IDNUM,
v.regdate,
v.birthdate,
convert(varbinary(max), v.signature) as signature
FROM pet_counts p
LEFT OUTER JOIN user_info v
ON p.IDNUM = v.IDNUM
LEFT OUTER JOIN vrpet vp
ON p.event = vp.event
AND p.PET_NUM = vp.PET_NUM
WHERE p.event = @event
and p.pet_num = @pet_num
ORDER BY pageid,
linenum
END
如果我没有在最终选择上做一个明确的操作,那么查询就会运行,但是我需要一个明确的,因为我正在返回重复的行。我猜这是因为图像领域。有没有更好/更有效的方法来进行这种性质的查询并返回正确数量的记录?
由于
答案 0 :(得分:3)
我已经看到许多问题成了问题,说'我必须保持不同,否则我会得到重复的行。'这只是现有问题中的另一个问题。它不仅是一个非常糟糕的绷带,它实际上是问题的一部分。
如果您不得不强制使用DISTINCT,则可能无法正确使用GROUP BY。我们还需要有关样本数据的更多信息。我的建议是停止查看整个代码片并将其全部搞清楚。我的建议是查看第一个选择,并确定你真的需要按所有这些字段进行分组。
Take it one piece at a time
@Newbie我还添加了评论:
@Newbie一次选择一个SELECT。获取一些数据,检查数据,看起来是否正常以及下一个内部选择。检查数据,确保GROUP BYs看起来不错,添加下一个SELECT。继续前进,直到看起来不错。
答案 1 :(得分:2)
大多数情况下,SQL查询并不慢,因为它们的重量级,但由于表模式(大小,基数,选择性,可用索引)。优化器可以从查询中理解很多,并且无论写得多么残酷,都可以对其进行优化。要回答有关SQL查询的任何性能问题,必须包括涉及的数据模式和表的大小。
引擎已经为您提供了很多帮助来回答您自己的问题。它提供了有关missing indexes的信息,它会跟踪个人query performance,文档涵盖basic recommendations。
答案 2 :(得分:1)
优化的第一步是将查询分成小部分。将每个零件作为一个步骤运行,并确定哪个零件受伤最严重。查询菜单中的“显示实际执行计划”选项可以提供很大的帮助。
一旦您发现查询的部分受到伤害,通常很容易看出它是如何改进的。如果您无法弄清楚,即使在尝试之后,您也可以在Stack Overflow上发帖,询问具体的建议。
答案 3 :(得分:0)
让我们看看这个:
case
when sum(case when INV_ADR = '1' then 1 else 0 end) > 0
then convert(varchar(5), sum(case when INV_ADR = '1' then 1 else 0 end)) + ' Invalid Addr'
else '' end as InvalidAddress
请注意,每行都会运行case(....)
。有很多这样的人。
似乎INV_ADR
是char()
试图伪造布尔值。现在,假设 INV_ADR
是tinyint
,默认为0,约束为(0,1)
您可以先(在子查询或cte中)简单地说:
sum(INV_ADR) AS [NumberOfInvalidAddr]
然后在另一个查询中 - 完成所有聚合后 - 引用第一个:
case
when [NumberOfInvalidAddr] > 0
then convert(varchar(5), [NumberOfInvalidAddr]) + ' Invalid Addr'
else '' end as InvalidAddress
应该更快。