【发布时间】:2019-05-05 09:08:32
【问题描述】:
在编写程序时,我遇到了一种情况,即我必须在查询中输入DISTINCT。这有点类似于我的表架构
CREATE TABLE T1
(
ID INT,
TypeID INT,
SubTypeID INT,
Name VARCHAR(50)
);
GO
CREATE TABLE T2
(
TypeID INT,
SubTypeID INT,
TypeName VARCHAR(50)
);
GO
INSERT INTO T2 (TypeID, SubTypeID, TypeName)
VALUES (1, 1, 'AAA'), (1, 2, 'AAA'),
(2, 1, 'BBB'), (2, 2, 'BBB'),
(3, 1, 'CCC'), (3, 2, 'CCC');
INSERT INTO T1 (ID, TypeID, SubTypeID, Name)
VALUES (1, 1, 1, 'ABC'), (2, 2, 2, 'BCD'),
(3, 3, 2, 'CDE'), (4, 1, 1, 'DEF'),
(5, 2, 2, 'EFG'), (6, 3, 0, 'FGH'); -- Sub Type not detected yet.
GO
在此,用户可以提供SubType或让系统检测。
现在我有 2 个用于此场景的查询选项。
选项 1
SELECT DISTINCT t1.ID, t1.Name, t2.TypeName
FROM T1
JOIN T2 ON T1.TypeID = T2.TypeID;
还有选项 2
SELECT t1.ID, t1.Name, t2.TypeName
FROM T1
JOIN (SELECT DISTINCT TypeID, TypeName FROM T2) AS T2 ON T1.TypeID = T2.TypeID;
这两种情况的结果是相同的,但我想知道哪个应该是首选。表 T1 中可能有数百万行,而 T2 中可能有数千行。
在我看来,我应该使用第一个选项来避免子查询。
但仍想与社区确认,因为它可能会对性能产生一些或主要的影响,目前尚不清楚。
【问题讨论】:
-
与大多数与性能相关的问题一样,您需要检查结果中的
execution plan以确定哪个查询会做得更好。假设t1.Id是主键,我想他们会有相同的计划。话虽如此,这些查询可能会根据数据产生不同的结果...... -
这取决于连接结果的大小,如果它足够大,那么从
T2中选择distinct会比从连接中选择distinct更快。第二个查询将提供一个较小的加入集合,这再次使其比第一个查询更快 -
@mangusta 是的,但在我看来,不利的一面是它不会获得应用在 T2 上的索引的好处,还是会?
-
@sgeddes 我知道执行计划,但我找不到任何区别,因为我只有非常少量的样本数据,而且产品还没有投入生产。而关于不同的结果,他们不会因为第一个表必须只有唯一的值。 [删除旧评论并为标签 sgeddes 添加新评论]
-
看看这个问题:stackoverflow.com/questions/27042524/can-you-index-subqueries 在 MySQL 的情况下,优化器也允许索引用于子查询结果。但是,MSSQL 可能并非如此
标签: sql sql-server performance tsql query-performance