Sql ows):
这种CTE比伊兹克的CTE执行更多的读取,但比传统的CTE执行更少的读取。 但是,它始终比其他查询执行更少的写入操作。 正如你所知,书写总是比阅读贵得多 持续时间在很大程度上取决于核心数(MAXDOP),但在我的8core上,执行速度始终比其他查询快(持续时间以毫秒为单位) 我正在使用:Sql ows):,sql,sql-server,Sql,Sql Server,这种CTE比伊兹克的CTE执行更多的读取,但比传统的CTE执行更少的读取。 但是,它始终比其他查询执行更少的写入操作。 正如你所知,书写总是比阅读贵得多 持续时间在很大程度上取决于核心数(MAXDOP),但在我的8core上,执行速度始终比其他查询快(持续时间以毫秒为单位) 我正在使用: Microsoft SQL Server 2012 - 11.0.5058.0 (X64) May 14 2014 18:34:29 Copyright (c) Microsoft Corporation
Microsoft SQL Server 2012 - 11.0.5058.0 (X64)
May 14 2014 18:34:29
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: )
Microsoft SQL Server 2012-11.0.5058.0(X64)
2014年5月14日18:34:29
版权所有(c)微软公司
Windows NT 6.3(内部版本9600:)上的企业版(64位)
在Windows Server 2012 R2上,32 GB,Xeon X3450@2.67Ghz,启用了4核HT。使用
SQL Server 2016+
生成数字表,您可以使用OPENJSON
:
-- range from 0 to @max - 1
DECLARE @max INT = 40000;
SELECT rn = CAST([key] AS INT)
FROM OPENJSON(CONCAT('[1', REPLICATE(CAST(',1' AS VARCHAR(MAX)),@max-1),']'));
取自
0
的想法通常很有用。我可能会将最后一列转换为int
。此外,您还应该知道,基本上该方法包含在已接受的答案中(没有0
或转换为int
),其名称为Itzik的交叉连接CTE方法。在视图中添加带SCHEMABINDING
的任何特殊原因?添加“带SCHEMABINDING”可以加快查询速度。它帮助优化器知道没有数据被访问。(见附件)我想知道@AnthonyFaull是否可以用一些测量数据来支持这一点。你能解释一下为什么你会这样做,而不是使用预先填充了数字的表格吗?例如,填充这样的表格。并非所有DBA和/或第三方应用程序都允许添加永久性表格。请投票选择不会浪费内存和IO的内置虚拟数字表格功能至少,你可能错过了一个更好的方法在[postgres]上做理货表是的,你做了@Conrad Frix,为迟到的问题道歉(晚了5年多),但是你做过任何性能测试来比较这个伟大的内置工具和其他方法吗?@JeffModen抱歉,没有,但它很容易测试。以Ruskin的查询为例,将其与call to generate series进行比较。@Conrad Frix,因为您声称自己具有性能,并且可以访问这两个环境(我没有),而且您也声称它很容易测试,所以我希望您能花些时间来测试它。;-)@康拉德·弗里克斯,嘿。。。你已经有了它的设置,你不能用5分钟来测试你自己声称的性能。NP继续,被公认的答案证明是错误的?虽然它看起来很漂亮,但它不是“最佳的”。我认为这取决于你的情况。在这两个性能最好的选项之间,您可以在IO和CPU成本之间进行权衡,这取决于对您来说什么更贵。IO几乎总是比CPU便宜,特别是因为这个表很小,可能已经在budferpool中了。@Denny先生的I/O总是比CPU更贵、更慢。SSD近年来在某种程度上改变了这一点,但在大多数生产体系结构中,这些SSD与CPU之间具有网络链路。我看到的唯一真正受CPU限制的数据库是运行非统一的ORM纯应用程序或繁重的机器学习。@rmalayter除非该表经常被使用,我们可以关心它,它几乎肯定会在内存中,内存升级更便宜,并且通常不会影响添加CPU核心的授权方式。SQL Server Enterprise edition将是一个5位数的核心,也就是说,添加核心在许可方面的成本可能比在服务器中投入更多ram的全部成本更高。很好。我想,如果SQL Server的XQuery中完全支持position()
,人们可能会使用类似的XML。很抱歉最近的评论,但该代码使用的CPU和逻辑读取(2000023)比Itik的级联CTE方法多11.4倍。我真的希望更多的人有你的社会责任感。除此之外,如果出于某种原因需要,您还需要为所有类型的内容填充一个数字表。感谢您的友好反馈,Andre。
SPID TextData Dur(ms) CPU Reads Writes
---- ---------------------------------------- ------- ----- ------- ------
51 --===== Test for 100 rows ============== 8 0 0 0
51 --===== Traditional RECURSIVE CTE method 16 0 868 0
51 --===== Traditional WHILE LOOP method CR 73 16 175 2
51 --===== Traditional CROSS JOIN table met 11 0 80 0
51 --===== Itzik's CROSS JOINED CTE method 6 0 63 0
51 --===== Housekeeping DROP TABLE #Tally 35 31 401 0
51 --===== Test for 1000 rows ============= 0 0 0 0
51 --===== Traditional RECURSIVE CTE method 47 47 8074 0
51 --===== Traditional WHILE LOOP method CR 80 78 1085 0
51 --===== Traditional CROSS JOIN table met 5 0 98 0
51 --===== Itzik's CROSS JOINED CTE method 2 0 83 0
51 --===== Housekeeping DROP TABLE #Tally 6 15 426 0
51 --===== Test for 10000 rows ============ 0 0 0 0
51 --===== Traditional RECURSIVE CTE method 434 344 80230 10
51 --===== Traditional WHILE LOOP method CR 671 563 10240 9
51 --===== Traditional CROSS JOIN table met 25 31 302 15
51 --===== Itzik's CROSS JOINED CTE method 24 0 192 15
51 --===== Housekeeping DROP TABLE #Tally 7 15 531 0
51 --===== Test for 100000 rows =========== 0 0 0 0
51 --===== Traditional RECURSIVE CTE method 4143 3813 800260 154
51 --===== Traditional WHILE LOOP method CR 5820 5547 101380 161
51 --===== Traditional CROSS JOIN table met 160 140 479 211
51 --===== Itzik's CROSS JOINED CTE method 153 141 276 204
51 --===== Housekeeping DROP TABLE #Tally 10 15 761 0
51 --===== Test for 1000000 rows ========== 0 0 0 0
51 --===== Traditional RECURSIVE CTE method 41349 37437 8001048 1601
51 --===== Traditional WHILE LOOP method CR 59138 56141 1012785 1682
51 --===== Traditional CROSS JOIN table met 1224 1219 2429 2101
51 --===== Itzik's CROSS JOINED CTE method 1448 1328 1217 2095
51 --===== Housekeeping DROP TABLE #Tally 8 0 415 0
WITH
E00 (N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ),
E01 (N) AS (SELECT a.N FROM E00 a CROSS JOIN E00 b),
E02 (N) AS (SELECT a.N FROM E01 a CROSS JOIN E01 b ),
E03 (N) AS (SELECT a.N FROM E02 a CROSS JOIN E02 b
LIMIT 11000 -- end record 11,000 good for 30 yrs dates
), -- max is 100,000,000, starts slowing e.g. 1 million 1.5 secs, 2 mil 2.5 secs, 3 mill 4 secs
Tally (N) as (SELECT row_number() OVER (ORDER BY a.N) FROM E03 a)
SELECT N
FROM Tally
CREATE VIEW dbo.Numbers
WITH SCHEMABINDING
AS
WITH Int1(z) AS (SELECT 0 UNION ALL SELECT 0)
, Int2(z) AS (SELECT 0 FROM Int1 a CROSS JOIN Int1 b)
, Int4(z) AS (SELECT 0 FROM Int2 a CROSS JOIN Int2 b)
, Int8(z) AS (SELECT 0 FROM Int4 a CROSS JOIN Int4 b)
, Int16(z) AS (SELECT 0 FROM Int8 a CROSS JOIN Int8 b)
, Int32(z) AS (SELECT TOP 2147483647 0 FROM Int16 a CROSS JOIN Int16 b)
SELECT ROW_NUMBER() OVER (ORDER BY z) AS n
FROM Int32
GO
--===== Hans CROSS JOINED CTE method
WITH Numbers_CTE (Digit)
AS
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9)
SELECT HundredThousand.Digit * 100000 + TenThousand.Digit * 10000 + Thousand.Digit * 1000 + Hundred.Digit * 100 + Ten.Digit * 10 + One.Digit AS Number
INTO #Tally5
FROM Numbers_CTE AS One CROSS JOIN Numbers_CTE AS Ten CROSS JOIN Numbers_CTE AS Hundred CROSS JOIN Numbers_CTE AS Thousand CROSS JOIN Numbers_CTE AS TenThousand CROSS JOIN Numbers_CTE AS HundredThousand
Microsoft SQL Server 2012 - 11.0.5058.0 (X64)
May 14 2014 18:34:29
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: )
-- range from 0 to @max - 1
DECLARE @max INT = 40000;
SELECT rn = CAST([key] AS INT)
FROM OPENJSON(CONCAT('[1', REPLICATE(CAST(',1' AS VARCHAR(MAX)),@max-1),']'));