![]() |
1
8
在拒绝之前,你真的测试过这个解决方案的性能吗?
如果速度很慢,可能是因为没有合适的索引。你有什么索引? |
![]() |
2
6
将其实现为聚合(例如,如果实现了“第一个非空”的sql clr聚合,则确实可以这样做)的问题是,当您通常只对前几行感兴趣时,浪费了读取每一行的io。聚合不会在第一个非空值之后停止,即使它的实现会忽略更多的值。聚合也是无序的,因此结果将取决于查询引擎选择的索引的顺序。 相比之下,子查询解决方案读取每个查询的最小行(因为您只需要第一个匹配的行)并支持任何排序。它还可以在数据库平台上工作,在这些平台上无法定义自定义聚合。 哪一个性能更好可能取决于表中的行数和列数以及数据的稀疏程度。其他行需要为聚合方法读取更多行。其他列需要其他子查询。稀疏数据需要检查每个子查询中的更多行。 以下是各种表格大小的一些结果:
这里测量的IO是逻辑读取数。请注意,子查询方法的逻辑读取数不会随表中的行数而改变。还要记住,每个附加子查询执行的逻辑读取很可能是针对相同的数据页(包含前几行)。另一方面,聚合必须处理整个表,并且需要一些cpu时间来处理。 这是我用来测试的代码…sortcol上的聚集索引是必需的,因为(在本例中)它将决定聚集的顺序。 定义表并插入测试数据:
查询表:
要测试的CLR“第一个非空”聚合:
|
![]() |
3
1
不是很优雅,但它可以在一个查询中完成。尽管这可能会使任何索引变得毫无用处,因此如前所述,多个子查询方法可能更快。
|
![]() |
4
1
这是另一种方法。如果数据库不允许子查询(如mine、teradata)中的top(n),那么这将是最有用的。
作为比较,下面是其他人提到的解决方案,使用
在一个理想的世界里,在我看来,这是最好的方法-干净,直观,高效(显然)。 或者您也可以这样做:
两个解决方案都沿着有序列检索“first”记录。
原因是
|
![]() |
Duvan · 将逗号(,)替换为点(.)[副本] 2 年前 |
![]() |
Mateen Bagheri · 选择表的计数并选择其自身 2 年前 |
![]() |
SoT · SQL Server中求和函数的工作方式 2 年前 |
![]() |
NKAT · 将列值聚合到列表中会产生错误 2 年前 |
![]() |
deanpillow · 返回两列中有一个匹配值的记录 3 年前 |
![]() |
snowflakes74 · 在Dapper中异步查询多个结果 3 年前 |