2017-02-13 5 views
0

Я закодирован следующий запрос:Как объединить два запроса по горизонтали?

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 или что

ответ

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