我编写了以下查询:
SELECT u.LastName Col1
, convert(varchar, COALESCE(COUNT(DISTINCT pm.PhraseId), 0)) AS Col2
, convert(varchar, COALESCE(COUNT(DISTINCT pc.PhraseId), 0)) AS Col3
FROM dbo.AspNetUsers u
LEFT JOIN dbo.Phrase pm ON u.Id = pm.ModifiedBy
LEFT JOIN dbo.Phrase pc ON u.Id = pc.CreatedBy
GROUP BY u.LastName
性能极差,运行时间超过一分钟。
然后我尝试将其分解为两个查询,每个查询只需两秒钟即可运行:
SELECT u.LastName Col1
, convert(varchar, COALESCE(COUNT(DISTINCT pm.PhraseId), 0)) AS Col2
FROM dbo.AspNetUsers u
LEFT JOIN dbo.Phrase pm ON u.Id = pm.ModifiedBy
GROUP BY u.LastName
SELECT u.LastName Col1
, convert(varchar, COALESCE(COUNT(DISTINCT pc.PhraseId), 0)) AS Col2
FROM dbo.AspNetUsers
LEFT JOIN dbo.Phrase pm ON u.Id = pc.CreatedBy
GROUP BY u.LastName
由于第一个查询不可运行,我想找到一些方法来组合两个较小查询的输出。 这是我想与表DDL相处的结果:
我有两张桌子:
CREATE TABLE [dbo].[Phrase] (
[PhraseId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[English] NVARCHAR (250) NOT NULL,
[CreatedBy] INT DEFAULT ((1)) NOT NULL,
[ModifiedBy] INT DEFAULT ((1)) NOT NULL,
PRIMARY KEY CLUSTERED ([PhraseId] ASC)
);
CREATE TABLE [dbo].[AspNetUsers] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[FirstName] NVARCHAR (MAX) NULL,
[LastName] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Col1 Col2 Col3
ad1 100 50
ad2 10 5
ad3 200 99
请注意,我的索引是这样的:
create nonclustered index ix_Phrase_CreatedBy on dbo.Phrase (CreatedBy)
create nonclustered index ix_Phrase_ModifiedBy on dbo.Phrase (ModifiedBy)
我很欣赏有关如何将较小的2秒运行时查询组合起来的建议,因为它似乎无论如何 我无法获得第一个快速运行的查询。不确定这是SQL Server问题还是
答案 0 :(得分:0)
使用Paste The Plan @ brentozar.com
分享您的执行计划正如我在这里提到的:Performance problems with two left joins. Is there an alternative with unpivot?
您也不需要使用count(distinct ...)
,因为PhraseId
是唯一的,或coalesce()
:
rextester:http://rextester.com/CMP5250
select
u.LastName
, CreatedByQty =count(pc.CreatedBy)
, ModifiedByQty=count(pm.ModifiedBy)
from dbo.AspNetUsers u
left join dbo.Phrase pc
on u.Id = pc.CreatedBy
left join dbo.Phrase pm
on u.Id = pm.ModifiedBy
group by u.LastName
你也可以尝试交换outer apply()
的左连接,但我不知道这是否会有所帮助:
select
u.LastName
, CreatedByQty =count(pc.CreatedBy)
, ModifiedByQty=pm.ModifiedByQty
from dbo.AspNetUsers u
left join dbo.Phrase pc
on u.Id = pc.CreatedBy
outer apply (
select ModifiedByQty=count(1)
from dbo.Phrase pm
where u.Id = pm.ModifiedBy
) pm
group by u.LastName