优化SQL以在Sybase Ase中透视表的最佳方法

优化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

我希望优化下面的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 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
    确认了非过程集合的过程方法,这将很慢(创建工作表;如果您的数据很大,工作表会很大),并且通过维度可以更快地获得相同的信息。为什么不使用此数据透视表的维度表?发布与此表或数据模型相关的所有维度表的DDL

  • 对评论的答复 我试图帮助你,但有两个障碍。首先,互动间隔19天。其次,您发布的SQL将不起作用:对于每一行,它在11列中返回相同的
    ColValue
    ;我无法理解您使用
    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