1
106
嗯…抱歉,我这么晚才回复一个旧邮件。而且,是的,我必须回答,因为这个线程上最流行的答案(当时,递归CTE的答案有14种不同方法的链接)是,嗯…性能最好是有挑战性的。 首先,有14个不同解决方案的文章可以看到动态创建数字/计数表的不同方法,但是正如文章和引用的线程中指出的,有一个 非常 重要引述…
具有讽刺意味的是,这篇文章本身包含了许多主观的陈述和“偏颇的指导方针”,例如 “递归CTE可以生成一个数字列表 效率相当高 “ 和 “这是 一种有效的方法 使用itzik ben gen发布的新闻组中的while循环” (我相信他只是为了比较的目的而张贴的)。伙计们…仅仅提到itzik的好名字,可能会导致一些可怜的笨蛋实际使用这种可怕的方法。作者应该实践他所宣扬的,在做出如此荒谬的错误陈述之前,特别是在面对任何可伸缩性之前,应该做一些性能测试。 考虑到在对任何代码做什么或某人“喜欢”做任何主观声明之前实际进行一些测试,下面是一些代码,您可以使用它们进行自己的测试。为运行测试的SPID设置探查器,并自己检查它…只需做一个“搜索‘不’替换’的数字1000000为您的“最爱”的数字,并看到…
在这里,我从SQL事件探查器中得到的值分别是100、1000、10000、100000和1000000…
正如你所看到的, 递归CTE方法在持续时间和CPU方面仅次于while循环,其逻辑读取形式的内存压力是while循环的8倍。 . 它是类固醇的RBAR,应该不惜一切代价避免任何单列计算,就像应该避免while循环一样。 有些地方递归很有价值,但这不是其中之一 . 作为副酒吧,丹尼先生绝对是…一个大小正确的永久数字或计数表是大多数事情的方法。正确的尺寸是什么意思?好吧,大多数人使用计数表来生成日期或对varchar(8000)进行拆分。如果您创建一个11000行计数表,在“n”上使用正确的聚集索引,那么您将有足够的行来创建超过30年的日期(我处理的抵押贷款相当多,因此30年是我的一个关键数字),当然也足以处理varchar(8000)拆分。为什么“正确的尺寸”如此重要?如果Tally表被大量使用,那么它很容易放在缓存中,这使得它非常快,而不会对内存造成太大压力。 最后但并非最不重要的是,每个人都知道,如果创建一个永久的计数表,那么使用哪种方法来构建它并不重要,因为1)它只会生成一次;2)如果它类似于11000行表,那么所有的方法都会运行得“足够好”。 那么,为什么我对使用哪种方法的理解都是靛蓝的呢???? 答案是,一些不太了解并且只需要完成工作的穷人/女孩可能会看到类似递归CTE方法的东西,并决定将其用于比构建永久计数表更大、更频繁使用的东西,我正在尝试 保护这些人,他们的代码运行的服务器,以及拥有这些服务器上数据的公司 . 是啊。。。这是一件大事。也应该是为其他人。教你正确的做事方法,而不是“足够好”。在发布或使用来自帖子或书籍的内容之前进行一些测试…事实上,你挽救的生命可能是你自己的,尤其是如果你认为递归CTE是实现这一目标的方法。;-) 感谢聆听… |
2
10
最理想的函数是使用表而不是函数。使用一个函数会导致额外的CPU负载为要返回的数据创建值,特别是当要返回的值覆盖非常大的范围时。 |
3
4
This article 给出14种可能的解决方案,并对每种方案进行讨论。重要的是:
我个人喜欢:
|
4
3
这个视图是超快速的,包含了所有积极的
|
5
1
使用
从中吸取的思想 How can we use OPENJSON to generate series of numbers? |
6
0
编辑:见下面康拉德的评论。 杰夫莫登的回答很好…但我在Postgres上发现,除非删除e32行,否则itzik方法会失败。 在Postgres上稍微快一点(40毫秒对100毫秒)是我在上发现的另一种方法 here 适合Postgres:
当我从SQL Server迁移到Postgres World时,可能错过了在该平台上做计数表的更好方法…整数()?序列(?) |
7
0
稍后,我想贡献一个稍有不同的“传统”CTE(不要触摸基表以获得行的数量):
该CTE的读取次数比itzik的CTE多,但比传统的CTE少。 但是,与其他查询相比,它始终执行较少的写入操作。 正如你所知道的,写作总是比阅读昂贵得多。 持续时间在很大程度上取决于核心数量(maxdop),但在我的8core上,执行速度比其他查询更快(ms持续时间更短)。 我正在使用:
在Windows Server 2012 R2上,32 GB,Xeon x3450@2.67GHz,启用4核HT。 |
Duvan · 将逗号(,)替换为点(.)[副本] 2 年前 |
Mateen Bagheri · 选择表的计数并选择其自身 2 年前 |
SoT · SQL Server中求和函数的工作方式 2 年前 |
NKAT · 将列值聚合到列表中会产生错误 2 年前 |
deanpillow · 返回两列中有一个匹配值的记录 2 年前 |
snowflakes74 · 在Dapper中异步查询多个结果 2 年前 |