有没有一种方法可以使此选择通过一次查找来检索相同的结果?


8

通过修改查询或影响优化器的策略,是否可以通过一次查找或扫描检索与以下相同的数据?

与此类似的代码和架构目前在SQL Server 2014中。

在此处输入图片说明

复制脚本。设定:

USE tempdb;
GO
IF OBJECT_ID('dbo.TestUpload', 'U') IS NOT NULL 
  DROP TABLE dbo.TestUpload; 


CREATE TABLE dbo.TestUpload(
    JobRunId bigint NOT NULL,
    ThingAName nvarchar(255) NOT NULL,
    ThingAType nvarchar(255) NOT NULL,
    ThingAGranularity nvarchar(255) NOT NULL,
    ThingBName nvarchar(255) NOT NULL,
    ThingBType nvarchar(255) NOT NULL,
    ThingBGranularity nvarchar(255) NOT NULL
);
CREATE CLUSTERED INDEX IX_JobRunId ON dbo.TestUpload (JobRunId);

GO

INSERT INTO dbo.TestUpload (JobRunId, ThingAName, ThingAType, ThingAGranularity, ThingBName, ThingBType, ThingBGranularity)
  VALUES (1, 'A', 'B', 'C', 'D', 'E', 'F');
GO 10

INSERT INTO dbo.TestUpload (JobRunId, ThingAName, ThingAType, ThingAGranularity, ThingBName, ThingBType, ThingBGranularity)
  VALUES (1, 'D', 'E', 'F', 'A', 'B', 'C');
GO 10

查询:

DECLARE @JobRunID bigint = 1;

SELECT JobRunId,
  ThingAName AS Name, 
  ThingAType AS [Type], 
  ThingAGranularity AS Granularity
FROM dbo.TestUpload
WHERE JobRunId = @JobRunID
UNION
SELECT JobRunId,
  ThingBName AS Name, 
  ThingBType AS [Type], 
  ThingBGranularity AS Granularity
FROM dbo.TestUpload
WHERE JobRunId = @JobRunID;

拆除:

IF OBJECT_ID('dbo.TestUpload', 'U') IS NOT NULL 
  DROP TABLE dbo.TestUpload;

我认为这可能不是理想的模型。我正在尝试从开发人员那里获取有关如何选择架构的更多信息,但很好奇我是否忽略了TSQL技巧,因为更改查询比架构更容易。

Answers:


6

我会尝试这样做,但我不知道它是否会更有效。您需要DISTINCT删除重复项,因此UNION ALL可能更合适,不需要两个不同的操作:

SELECT DISTINCT 
    JobRunId = @JobRunID, 
    d.*
FROM dbo.TestUpload
  CROSS APPLY 
    (   SELECT 
          ThingAName AS Name, 
          ThingAType AS [Type], 
          ThingAGranularity AS Granularity
      UNION                            -- or UNION ALL
        SELECT 
          ThingBName, 
          ThingBType, 
          ThingBGranularity
    ) AS d 
WHERE JobRunId = @JobRunID ;

UNION ALL 计划:

UNION ALL计划

UNION 计划:

联盟计划


3

使用交叉应用将列取消透视成行

SELECT --DISTINCT most probably
  JobRunId,
  ut.Name, 
  ut.[Type], 
  ut.Granularity
FROM dbo.TestUpload
CROSS APPLY (
  SELECT ThingBName AS Name, 
  ThingBType AS [Type], 
  ThingBGranularity AS Granularity
  UNION ALL 
  SELECT ThingAName AS Name, 
  ThingAType AS [Type], 
  ThingAGranularity AS Granularity
  ) ut
WHERE JobRunId = @JobRunID

1
不,我也这么认为,但这是行不通的。甚至没有,UNION因为必须删除重复项。
ypercubeᵀᴹ

您的意思是不可避免的吗?
Serg

1
我的意思DISTINCT是必须的。参见詹姆斯的数据。有一行,A,B,C,-,-,-另一行是-,-,-,A,B,C。来自A数据的结果行和来自B数据的结果行是相同的,必须删除。即使将UNION ALL替换为UNION,也无法避免。(对于“ this”,我的意思不是“ sort”,而是“ distinct”操作。它可能与sort或hash无关,无论优化程序可以选择使用
哪种
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.