在派生表上使用CTE是否有任何性能提升?
performance sql-server-2005 derived-table common-table-expression
我编写了一个表值UDF,它以CTE开头,从大表中返回行的子集.CTE中有几个连接.一对内部和一个左边连接到其他表,这些表不包含很多行.CTE有一个where子句,它返回日期范围内的行,以便只返回所需的行.
然后,我在4个自左连接中引用此CTE,以便使用不同的标准构建小计.
查询非常复杂,但这是一个简化的伪版本
WITH DataCTE as
(
SELECT [columns] FROM table
INNER JOIN table2
ON [...]
INNER JOIN table3
ON [...]
LEFT JOIN table3
ON [...]
)
SELECT [aggregates_columns of each subset] FROM DataCTE Main
LEFT JOIN DataCTE BananasSubset
ON [...]
AND Product = 'Bananas'
AND Quality = 100
LEFT JOIN DataCTE DamagedBananasSubset
ON [...]
AND Product = 'Bananas'
AND Quality < 20
LEFT JOIN DataCTE MangosSubset
ON [...]
GROUP BY [
Run Code Online (Sandbox Code Playgroud)
我觉得SQL Server会感到困惑并为每次自我加入调用CTE,这似乎通过查看执行计划得到了证实,尽管我承认自己并不是那些阅读它们的专家.
我会假设SQL Server足够聪明,只能从CTE执行一次数据检索,而不是多次执行.
我尝试了相同的方法,但不是使用CTE来获取数据的子集,我使用了与CTE中相同的选择查询,而是将其输出到临时表.
引用CTE版本的版本需要40秒.引用临时表的版本需要1到2秒.
为什么SQL Server不够智能,无法将CTE结果保留在内存中? …
如何从while循环
我的循环创建sql server cte 像这样
declare @ind as int
declare @code as nvarchar
set @ind = 0
while @ind < 884
begin
select @ind = @ind + 1
--here execute Procedure
--and set return value to variable
set @code = cast (@ind as nvarchar)
end
Run Code Online (Sandbox Code Playgroud) 这是我在PostgreSQL中遇到的问题的简化版本.
我有下表A:
[ID INTEGER | VALUE NUMERIC(10,2) | 家长 整数 ]
其中'PARENT'是列引用ID的自引用FK.
表定义是:
CREATE TABLE A(ID INTEGER IDENTITY, VALUE NUMERIC(10,2), PARENT INTEGER)
ALTER TABLE A ADD CONSTRAINT FK FOREIGN KEY (PARENT) REFERENCES A(ID)
Run Code Online (Sandbox Code Playgroud)
这个简单的表允许定义任意深度的树数据结构.现在我需要编写一个SQL(我不想使用服务器端PL-SQL)来报告每个节点,子树的总值"悬挂"在它下面.例如,使用下表:
| ID | VALUE | PARENT |
-------------------------
| 1 | NULL | NULL |
| 2 | 3.50 | 1 |
| 3 | NULL | NULL |
| 4 | NULL | 3 |
| 5 | 1.50 | 4 |
| …Run Code Online (Sandbox Code Playgroud) 问题
在过去的几个月中,下面描述的程序在其运行的绝大部分时间内都没有任何问题(2008年r2).但是,我们有三个错误连接数据的实例.问题是,造成这种情况的原因是什么以及如何解决这个问题?
DATA_PreImp
sourceid col01 col02 col03 col04 col...
100001 John Smith
100002 Calvin Klein
100003 Peter Parker
100004 Moe Greene
Run Code Online (Sandbox Code Playgroud)
通常,渲染结果是属性正确连接到Items_Main,但有时(小于1%)订单被加扰,因此col01的值没有连接到与其余列的值相同的Items_Main.
任何有关造成这种情况的见解都将是最受欢迎的.
数据移动程序
我们有一个SSIS包,它将数据从名为DATA_PreImp的平面表传输到由三个相关表组成的结构(基于属性).
SSIS包中的第一步将DATA_PreImp中的数据插入Items_Main,并将生成的标识符插入空DATA_PreImpMappingTMP表的TARGET_ID列中.
insert into items_main(creationdate, status)
output inserted.itemid into DATA_PreImpMappingTMP(TARGET_ID)
select getdate(), '0' from data_preimp
order by sourceid asc;
Run Code Online (Sandbox Code Playgroud)
SSIS包中的第二步使用TARGET_ID(最初为Itemid)填充Items_MainRel表,并使用该功能的标识符(在本例中为5).
insert into items_mainrel(itemid, featureid)
output inserted.itemrelid into DATA_PreImpMapping2TMP(INDREL_ID)
select TARGET_ID, 5 from DATA_PreImpMappingTMP
order by TARGET_ID asc;
Run Code Online (Sandbox Code Playgroud)
第三步是使用DATA_PreImp中的SOURCE_ID填充DATA_PreImpMapping2TMP表中的SOURCE_ID列.
with cte as (select sourceid, row_number() over (order by sourceid asc) as row from data_preimp) …Run Code Online (Sandbox Code Playgroud) 我对postgresql 9.2系统有一个查询,它的正常形式大约需要20秒,但在使用CTE时只需要大约120ms.
为简洁起见,我简化了两个查询.
这是正常形式(大约需要20秒):
SELECT *
FROM tableA
WHERE (columna = 1 OR columnb = 2) AND
atype = 35 AND
aid IN (1, 2, 3)
ORDER BY modified_at DESC
LIMIT 25;
Run Code Online (Sandbox Code Playgroud)
以下是此查询的说明:http://explain.depesz.com/s/2v8
CTE表格(约120ms):
WITH raw AS (
SELECT *
FROM tableA
WHERE (columna = 1 OR columnb = 2) AND
atype = 35 AND
aid IN (1, 2, 3)
)
SELECT *
FROM raw
ORDER BY modified_at DESC
LIMIT 25;
Run Code Online (Sandbox Code Playgroud)
以下是CTE的解释:http://explain.depesz.com/s/uxy
只需ORDER …
无法弄清楚如何使用多个CTE
这失败了
; with [cteOne] as (
select 1 as col
),
[cteTwo] as (
select 2 as col
)
select 'yesA' where exists (select * from [cteOne])
select 'yexB' where exists (select * from [cteTwo])
Run Code Online (Sandbox Code Playgroud)
这有效 - 但这不是我需要的
; with [cteOne] as (
select 1 as col
),
[cteTwo] as (
select 2 as col
)
select * from [cteOne]
union
select * from [cteTwo]
Run Code Online (Sandbox Code Playgroud)
真正的语法是row_number()分区的连接
我刚刚使用派生表
我创建一个大型查询作为公用表表达式 - month_index using WITH子句.是否可以在交叉表查询的源代码sql中引用此公用表表达式?
当我确实得到错误关系"month_index"不存在
WITH month_index AS
(
SELECT ...
)
SELECT * FROM CROSSTAB(
'SELECT rowid AS row_name,
CONCAT(''m'',monthno) AS category,
nic5dindex AS value
FROM month_index',
'*<categorysql>*')
AS ct(..)
Run Code Online (Sandbox Code Playgroud)
我使用Postgresql 9.3.
我正在运行一系列生成数据库的脚本.它们在SQL Server 2012(11.0.5058.0)上运行完成.在SQL Server 2014(12.0.4213.0)上,脚本错误:
消息0,级别11,状态0,行0
当前命令发生严重错误.结果(如果有的话)应该被丢弃.消息0,级别20,状态0,行0
当前命令发生严重错误.结果(如果有的话)应该被丢弃.
看来,IsNumeric在CTE查询中使用语句的结果会破坏查询构建,因为不需要行来导致错误.我遇到的案例的简化版本是:
CREATE TABLE #Temp1 ( CTECol VARCHAR );
CREATE TABLE #Temp2 ( NumCol Int null);
;
WITH cte AS
(
SELECT
CASE WHEN ISNUMERIC(t.CTECol) = 1
THEN 1
ELSE null
END as IsNCol1
FROM
#Temp1 t
)
SELECT *
FROM #Temp2
JOIN cte ON #Temp2.NumCol = cte.IsNCol1
Run Code Online (Sandbox Code Playgroud)
我能找到的最简单的案例是:
CREATE TABLE #Temp3 ( CTECol Int );
CREATE TABLE #Temp4 ( NumCol Int );
;
WITH cte AS
(
SELECT ISNUMERIC(t.CTECol) …Run Code Online (Sandbox Code Playgroud) sql-server isnumeric common-table-expression sql-server-2014
有人可以解释一下为什么这个脚本会返回'some_word'但是没有关于不存在的模式试图从中检索数据的错误schema_that_doesnt_exist.tab吗?
with tab as
(
select 'some_word' str
from dual
)
select *
from schema_that_doesnt_exist.tab;
Run Code Online (Sandbox Code Playgroud)
有关此问题的Oracle文档中的某些URL也对我有所帮助.
sql ×4
sql-server ×4
postgresql ×3
performance ×2
crosstab ×1
isnumeric ×1
oracle ×1
ssis ×1
t-sql ×1
temp-tables ×1