我想从字段中找到最高的AutoIncremented值。 (在我可以使用@@SCOPE_IDENTITY
等插入后,它不被取出)
这两个查询中的哪一个会运行得更快或性能更好。
Id
是autoincrement
的主键和Table1
字段。这适用于Sql Server 2005.
SELECT MAX(Id) FROM Table1
SELECT TOP 1 Id FROM Table1 ORDER BY Id DESC
[编辑]
在这种情况下,是Id
是我已定义聚簇索引的字段
如果索引是ID DESC
那么什么..
是的,如果知道如何影响性能会很好
1. Id是聚簇索引+主键
2. Id是聚簇索引而不是主键
3. Id是非聚集索引ASC +主键
4. Id是非聚集索引ASC而不是主键
5. Id是非聚集索引DESC +主键
6. Id是非聚集索引DESC而不是主键
7. Id只是AutoIncrement
希望它不是一个很高的命令!
答案 0 :(得分:9)
如果存在聚集索引,则两个查询之间的性能几乎没有差异。
这是因为它们都会执行聚集索引扫描,它将承担100%的查询费用。
对没有索引的列执行两个查询会导致在两个执行计划中使用3个运算符。
Top子句使用Sort运算符,Max函数使用Stream Aggregate运算符。
当没有索引时,MAX()函数提供更好的性能。
可以找到概念证明,并且可以找到测试场景的完整演练here
答案 1 :(得分:9)
没人提到IDENT_CURRENT('Table1') - 将它们全部吹走 - 当然它只适用于标识列,但是问题......
答案 2 :(得分:7)
从理论上讲,他们会使用相同的计划并且几乎同时运行。
在实践中,
SELECT TOP 1 Id FROM Table1 ORDER BY Id DESC
更可能使用PRIMARY KEY INDEX
。
此外,如果您决定选择其他列以及id
,则此广告更具扩展性。
MAX()
上的实际计划说:
SELECT <- AGGREGATE <- TOP <- CLUSTERED INDEX SCAN
,而TOP 1
的计划说:
SELECT <- TOP <- CLUSTERED INDEX SCAN
,我。即aggregate
被省略。
聚合实际上不会在这里做任何事情,因为只有一行。
P上。 S。注意到@Mehrdad Afshari
和@John Sansom
,在非索引字段MAX
上稍快一些(当然不是优化程序所说的20
次):< / p>
-- 18,874,368 rows SET LANGUAGE ENGLISH SET STATISTICS TIME ON SET STATISTICS IO ON PRINT 'MAX' SELECT MAX(id) FROM master PRINT 'TOP 1' SELECT TOP 1 id FROM master ORDER BY id DESC PRINT 'MAX' SELECT MAX(id) FROM master PRINT 'TOP 1' SELECT TOP 1 id FROM master ORDER BY id DESC PRINT 'MAX' SELECT MAX(id) FROM master PRINT 'TOP 1' SELECT TOP 1 id FROM master ORDER BY id DESC PRINT 'MAX' SELECT MAX(id) FROM master PRINT 'TOP 1' SELECT TOP 1 id FROM master ORDER BY id DESC PRINT 'MAX' SELECT MAX(id) FROM master PRINT 'TOP 1' SELECT TOP 1 id FROM master ORDER BY id DESC Changed language setting to us_english. SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. MAX SQL Server Execution Times: CPU time = 0 ms, elapsed time = 20 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 447, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 5452 ms, elapsed time = 2766 ms. TOP 1 SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 2, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 6813 ms, elapsed time = 3449 ms. MAX SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 44, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 5359 ms, elapsed time = 2714 ms. TOP 1 SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 6766 ms, elapsed time = 3379 ms. MAX SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 5406 ms, elapsed time = 2726 ms. TOP 1 SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 6780 ms, elapsed time = 3415 ms. MAX SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 85, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 5392 ms, elapsed time = 2709 ms. TOP 1 SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 10, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 6766 ms, elapsed time = 3387 ms. MAX SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 5374 ms, elapsed time = 2708 ms. TOP 1 SQL Server Execution Times: CPU time = 0 ms, elapsed time = 1 ms. (строк обработано: 1) Table 'master'. Scan count 3, logical reads 32655, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 6797 ms, elapsed time = 3494 ms.
答案 3 :(得分:3)
只需比较执行计划,您就会看到(在编辑查询时按下Management Studio中的Ctrl+M
)。我的猜测是,如果Id
列上有(聚集的)索引,这些查询同样具有高效性。
然而,这整体上是非常糟糕的想法。
答案 4 :(得分:2)
MAX
通常更快。
如果存在,两个查询都将使用列上的索引。
如果列中不存在索引,则TOP 1
查询将使用Top N Sort
运算符排序表而不是流聚合,这会让它变慢。
MAX
也提供了更好的可读性。
Side Note :虽然MAX
将在索引案例中的执行计划中使用流聚合运算符,但它没有任何特定成本,因为它只处理单行( Actual Rows = 1
)。您可以通过在一个批处理中运行查询来比较查询,并查看相对成本。在索引的情况下,两个查询都将花费50%。我在一张大约7000行的表格上测试了非索引的情况,与MAX相比,TOP的成本为65%,费用为35%。
答案 5 :(得分:2)
我刚刚测试了您针对典型数据集提供的两个SQL语句:
SELECT MAX(Id) FROM Table1
SELECT TOP 1 Id FROM Table1 ORDER BY Id DESC
SELECT TOP 1 Id FROM Table1 ORDER BY Id DESC
稍快一点,因为它在执行计划中有最后一步。以下是每个查询执行的执行计划:
SELECT MAX(Id)FROM Table1
聚集索引扫描&gt;&gt;顶部&gt;&gt;流聚合&gt;&gt;选择
SELECT ONE 1 Id FROM Table1 ORDER BY Id DESC
聚集索引扫描&gt;&gt;顶部&gt;&gt;选择
答案 6 :(得分:1)
是的,在这种情况下,Id是字段 我已经定义了群集 指数。如果索引是ID DESC那么 什么..是的,它会很好 知道性能如何 如果
受到影响
- Id是聚集索引+主键。
- Id是聚集索引,而不是主键。
- Id是非聚集索引ASC +主键。
- Id是非聚集索引ASC,而不是主键。
- Id是非聚集索引DESC +主键。
- Id是非聚集索引DESC而不是主键。
- Id只是AutoIncrement
醇>
对于案例1和案例2,两者都将执行返回单个记录的聚簇索引扫描。两个查询之间没有IO差异。
对于案例3,4,5和6,两者都将执行返回单个记录的索引扫描。两个查询之间没有IO差异。
对于案例7,两者都将执行表扫描。 IO成本没有差异。
总结:案例1-6取胜!如果你在案例7中,那么你已经从IO的角度失去了。
您可以使用SQL的查询分析器来测量IO。在查询之前运行此命令。
SET STATISTICS IO ON