优化SQL以在Sybase Ase中透视表的最佳方法
我希望优化下面的SQL语句,该语句正在从历史表创建数据透视结果集。这可能已经是最符合共振峰的方法了,但我一直认为必须有更符合共振峰的方法 我正在尝试优化的SQL语句优化SQL以在Sybase Ase中透视表的最佳方法,sql,sap-ase,Sql,Sap Ase,我希望优化下面的SQL语句,该语句正在从历史表创建数据透视结果集。这可能已经是最符合共振峰的方法了,但我一直认为必须有更符合共振峰的方法 我正在尝试优化的SQL语句 select Col1, Col2, Max(case when TypeId = 1 then ColValue end) as Pivot1, Max(case when TypeId = 2 then ColValue end) as Pivot2, Max(case when TypeId = 3 then ColValue
select Col1, Col2,
Max(case when TypeId = 1 then ColValue end) as Pivot1,
Max(case when TypeId = 2 then ColValue end) as Pivot2,
Max(case when TypeId = 3 then ColValue end) as Pivot3,
Max(case when TypeId = 4 then ColValue end) as Pivot4,
Max(case when TypeId = 5 then ColValue end) as Pivot5,
Max(case when TypeId = 6 then ColValue end) as Pivot6,
Max(case when TypeId = 7 then ColValue end) as Pivot7,
Max(case when TypeId = 8 then ColValue end) as Pivot8,
Max(case when TypeId = 9 then ColValue end) as Pivot9,
Max(case when TypeId = 10 then ColValue end) as Pivot10,
Max(case when TypeId = 11 then ColValue end) as Pivot11
from RowTable
group by Col1, Col2
更新:以下是表格定义
CREATE TABLE dbo.RowTable (
Id int NOT NULL,
Col1 char(8) NOT NULL,
Col2 tinyint NOT NULL,
TypeId int NOT NULL,
ColValue datetime NOT NULL,
CreatedBy varchar(50) NOT NULL,
Rowstamp timestamp NOT NULL
)
LOCK DATAROWS
GO
ALTER TABLE dbo.RowTable
ADD CONSTRAINT ukRowTable
UNIQUE (Col1, Col2, TypeId)
WITH max_rows_per_page = 0, reservepagegap = 0
旋转本身就是一种昂贵的操作。我不认为这是可以优化的。回答原始问题 一,。表的性能保持不变。
好的,在任何人可以评估代码之前,从性能角度来看,我们需要CREATETABLE语句,包括索引
数据透视是以行、列的形式表示可用数据的功能。如果数据库(表)被规格化为3NF或5NF,这是面向行的,那么对行对象执行列函数的速度会很慢。与产品无关。如果您想要快速访问列(用于数据透视或任何其他列函数),则需要6NF中的数据。这也恰好使任务所需的SQL更加直截了当 如果您的数据建模师准备了数据透视表(通常是数据仓库类型的用法;维度事实结构),那么它可能不是真的6NF,但至少比5NF好,并且更容易提取数据透视值。当我看到DDL时,我将能够确定它是什么(真正的6NF;优于5NF但不是6NF)。然后我可以确定您是否正在使用最佳代码来获得所需的内容 只有当桌子不在6NF时,它才缓慢或“昂贵”
MAX()
(调用结果列Pivotx
不会使它成为轴心);你每一行都读一次。也就是说,你有一种程序性的思维方式,而不是以数据为中心或以集合为导向的思维方式。因此,代码很可能无法获得所需的值(性能是否良好,是另一个问题)
您使用GROUP BY
确认了非过程集合的过程方法,这将很慢(创建工作表;如果您的数据很大,工作表会很大),并且通过维度可以更快地获得相同的信息。为什么不使用此数据透视表的维度表?发布与此表或数据模型相关的所有维度表的DDLColValue
;我无法理解您使用MAX()
的目的。好的,需要使用MAX()
来击败分组提交。因此,我仍然不知道您的意图(而不是您编码的内容)。混淆是公平的,但在这里我们失去了意义
是的,有更快的方法,但我需要了解意图和父表(例如,您有一个(Col1,Col2)的表吗
是唯一的吗?如果它是一个数据库,那么表不是独立的,它们是相关的,它们之间的关系有一定的用途。我意识到你并不认为它们是相关的,但这种限制产生了你发布的代码;解决方案是超出了这个限制
无论如何,为了避免进一步延迟,请尝试此代码。这只是一个猜测,对我来说似乎不正确,因为(Col1,Col2,TypeId)
是唯一的;因此每个Col1,Col2
结果行只有一组TypeId
(结果集中的列标题):
[Superceded, refer below]
如果没有父表(即,它不是关系数据库),请使用SELECT-INTO
动态创建一个父表,或使用派生表:SELECT Col1,
SELECT Col1,
Col2,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 1 ) as Latest_1,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 2 ) as Latest_2,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 3 ) as Latest_3,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 4 ) as Latest_4,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 5 ) as Latest_5,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 6 ) as Latest_6,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 7 ) as Latest_7,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 8 ) as Latest_8,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 9 ) as Latest_9,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId=10 ) as Latest_10,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId=11 ) as Latest_11
FROM (
SELECT DISTINCT
Col1,
Col2
FROM RowTable
) OUTER
Col2,
(从Col1=OUTER.Col1和Col2=OUTER.Col且TypeId=1的行表中选择ColValue)作为最新的_1,
(从行表中选择ColValue,其中Col1=OUTER.Col1和Col2=OUTER.Col,TypeId=2)作为最新的_2,
(从行表中选择ColValue,其中Col1=OUTER.Col1和Col2=OUTER.Col,TypeId=3)作为最新的_3,
(从Col1=OUTER.Col1和Col2=OUTER.Col且TypeId=4的行表中选择ColValue)作为最新的_4,
(从Col1=OUTER.Col1和Col2=OUTER.Col且TypeId=5的行表中选择ColValue)作为最新的_5,
(从Col1=OUTER.Col1和Col2=OUTER.Col且TypeId=6的行表中选择ColValue)作为最新的_6,
(从行表中选择ColValue,其中Col1=OUTER.Col1和Col2=OUTER.Col,TypeId=7)作为最新的_7,
(从Col1=OUTER.Col1和Col2=OUTER.Col且TypeId=8的行表中选择ColValue)作为最新的_8,
(从行表中选择ColValue,其中Col1=OUTER.Col1和Col2=OUTER.Col,TypeId=9)作为最新的_9,
(从Col1=OUTER.Col1和Col2=OUTER.Col且TypeId=10的行表中选择ColValue)作为最新的_10,
(从Col1=OUTER.Col1和Col2=OUTER.Col且TypeId=11的行表中选择ColValue)作为最新的_11
从(
选择不同的
Col1,
可乐
从RowTable开始
)外部
您可以去掉行表中的Id
列,它是一个100%冗余的列和索引,没有任何用途
我已经发布了CREATETABLE语句(见上文)。该表是一个历史表,因此每当用户执行操作时,日期都会被放入ColValue列中,操作类型进入TypeID,Col1/Col2用于返回操作所执行的内容(Col1是外键)@好的,这是一种审计表,是某个表的子表,Col1
是PK。我的意思是,请为所有父表提供DDL。它们是什么
SELECT Col1,
Col2,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 1 ) as Latest_1,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 2 ) as Latest_2,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 3 ) as Latest_3,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 4 ) as Latest_4,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 5 ) as Latest_5,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 6 ) as Latest_6,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 7 ) as Latest_7,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 8 ) as Latest_8,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 9 ) as Latest_9,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId=10 ) as Latest_10,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId=11 ) as Latest_11
FROM (
SELECT DISTINCT
Col1,
Col2
FROM RowTable
) OUTER