如果我有一张桌子
CREATE TABLE users (
id int(10) unsigned NOT NULL auto_increment,
name varchar(255) NOT NULL,
profession varchar(255) NOT NULL,
employer varchar(255) NOT NULL,
PRIMARY KEY (id)
)
我想获得所有专业领域的独特价值,什么会更快(或建议):
SELECT DISTINCT u.profession FROM users u
or
SELECT u.profession FROM users u GROUP BY u.profession
?
对于单个列上的DISTINCT和单个列上的GROUP BY,上面的所有答案都是正确的。
每个db引擎都有自己的实现和优化,如果你只关心一点点差异(在大多数情况下),那么你必须针对特定的服务器和特定的版本进行测试!由于实现可能会改变…
但是,如果在查询中选择多个列,则DISTINCT本质上是不同的!因为在这种情况下,它将比较所有行的所有列,而不仅仅是一列。
如果你有这样的东西:
// This will NOT return unique by [id], but unique by (id,name)
SELECT DISTINCT id, name FROM some_query_with_joins
// This will select unique by [id].
SELECT id, name FROM some_query_with_joins GROUP BY id
认为DISTINCT关键字通过指定的第一列来区分行是一个常见的错误,但DISTINCT是这种方式的通用关键字。
所以朋友们,你们要小心,不要把上面的答案当成所有情况下的正确答案……你可能会感到困惑,得到错误的结果,而你想要的只是优化!
如果问题允许,请尝试使用EXISTS,因为它被优化为只要找到结果就结束(并且不缓冲任何响应),因此,如果您只是试图为这样的WHERE子句规范化数据
SELECT FROM SOMETHING S WHERE S.ID IN ( SELECT DISTINCT DCR.SOMETHING_ID FROM DIFF_CARDINALITY_RELATIONSHIP DCR ) -- to keep same cardinality
更快的回答是:
SELECT FROM SOMETHING S WHERE EXISTS ( SELECT 1 FROM DIFF_CARDINALITY_RELATIONSHIP DCR WHERE DCR.SOMETHING_ID = S.ID )
这并不总是可行的,但当可用时,你会看到一个更快的响应。
经过大量的测试,我们得出的结论是GROUP BY更快
选择sql_no_cache
opnamegroep_intern
从telwerken
WHERE opnemergroep IN (7,8,9,10,11,12,13) group by opnamegroep_intern
总共0.0944秒
显示记录0 - 29(共635条,查询持续0.0484秒)
选择sql_no_cache
不同的(opnamegroep_intern)
从telwerken
WHERE opnemergroep IN (7,8,9,10,11,12,13)
635总共0.2117秒(几乎慢了100%)
韦格弗面包车记录0 - 29(总共635,查询时间0.3468秒)
下面是一个简单的方法,它将为每个查询打印2个不同的运行时间。
DECLARE @t1 DATETIME;
DECLARE @t2 DATETIME;
SET @t1 = GETDATE();
SELECT DISTINCT u.profession FROM users u; --Query with DISTINCT
SET @t2 = GETDATE();
PRINT 'Elapsed time (ms): ' + CAST(DATEDIFF(millisecond, @t1, @t2) AS varchar);
SET @t1 = GETDATE();
SELECT u.profession FROM users u GROUP BY u.profession; --Query with GROUP BY
SET @t2 = GETDATE();
PRINT 'Elapsed time (ms): ' + CAST(DATEDIFF(millisecond, @t1, @t2) AS varchar);
或尝试设置统计时间(Transact-SQL)
SET STATISTICS TIME ON;
SELECT DISTINCT u.profession FROM users u; --Query with DISTINCT
SELECT u.profession FROM users u GROUP BY u.profession; --Query with GROUP BY
SET STATISTICS TIME OFF;
它简单地显示了解析、编译和执行每条语句所需的毫秒数,如下所示:
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 2 ms.