IBM Cognos 最佳实践: 改进 IBM Cognos Report Studio 的主/细报表性能

产品:IBM Cognos 8;关注领域:性能

本文将介绍一种 IBM Cognos Report Studio 报表设计技术,可将它应用于针对关系数据源运行的主/细型报表。

Daniel Wagemann, Cognos 最佳实践顾问, IBM

Daniel Wagemann 是位于加拿大的 Business Analytics 的一名 IBM Cognos 可靠实践顾问。在他从事 IBM Cognos 产品套件的 11 年中,他对 IBM Cognos 部署的所有领域有了广阔的理解。他的专业领域包括课程开发、技术写作、咨询和客户支持。可在 Proven Practices Site 的几乎所有领域内找到他的作品。



George Xu, 高级开发人员, IBM

George Xu 是一名 IBM 客户服务管理人员。担任了 9 年的 IBM Cognos 3LS 组织高级开发人员,他专门研究 Cognos BI 系统可伸缩性、稳定性和性能问题。他拥有 BI 产品系列的广泛知识,包括数据访问、演示、内容管理、安全、数据建模和系统优化。George Xu 拥有工程专业硕士学位,他还获得了 Oracle DBA 和 PMP® 认证。他还曾担任过 Nortel 的开发经理。



Henk Cazemier, 高级软件开发人员, IBM

Henk Cazemier 是一名 IBM 客户服务管理人员。他担任 IBM Cognos 高级软件开发人员已有 25 年。他是关系查询计划方面的专家,深入研究了 Framework Manager 和 Cognos BI 报表产品。Henk 研究过各种与性能和可伸缩性相关的问题,拥有将 Framework Manager 模型转换为 SQL 以便有效访问建模数据的丰富知识。



2012 年 5 月 10 日

免费下载:IBM® Cognos® Express V9.5 或者 Cognos® 8 Business Intelligence Developer Edition V8.4 试用版
下载更多的 IBM 软件试用版,并加入 IBM 软件下载与技术交流群组,参与在线交流。

简介

目的

本文介绍一种 IBM Cognos Report Studio 报表设计技术,它可用于针对一个关系数据源运行的主/细型报表。

适用性

本文中列出的技术和产品特征均通过 Go Sales (Query) 和 Go Sales (Analysis) 包以及以下版本进行了验证:

  • IBM Cognos BI 8.4.1
  • IBM Cognos BI 10

警告

本文列出的技术只作为证明概念而创建的,可能不适用于所有的主/细场景。此技术应该在开发环境中进行全面测试后,再部署到生产环境中。


主/细的概述

主/细型报表是由一个主查询引用和一个细节查询引用所组成的。这些查询引用通过主/细关系连接起来。此关系用于筛选主查询中每条记录的细节查询,进而生成多个将发布到底层数据库的细节查询。随着主查询记录集不断增加,细节查询也会增加,从而减低整体报表的性能。

在下面的场景中,报表作者创建了一个 IBM Cognos Report Studio 报表,该报表显示了一个交叉表,表中含有 Product line 行、Year 列、以及 Quantity 度量单位。使用 Order 方法对报表进行了分隔。该报表布局如下屏幕截图所示。

图 1 按主/细关系显示交叉表和列表的 IBM Cognos Report Studio 报表布局
图 1 按主/细关系显示交叉表和列表的 IBM Cognos Report Studio 报表布局

当在 IBM Cognos Viewer 内执行此报表时,它会生成一个输出以显示每个 E-mail、Fax 和Mail Order 方法的标题。它还针对每一个标题显示一个交叉表,表中含有 Product line 行、Year 列和 Quantity 度量单位。这些交叉表中的每个值均由 Order 方法进行过滤。IBM Cognos Viewer 中的报表输出如下屏幕截图所示。

图 2 主/细型报表的 IBM Cognos Viewer 输出
图 2 主/细型报表的 IBM Cognos Viewer 输出

执行此报表时,查询数据库上的结构化查询语言 (SQL) 跟踪会显示,将为每个 Order 方法发送一次用于填充交叉表的 SQL。由于总共有 7 个 Order 方法,所以会向数据库发送 7 次细节查询。

在主/细型报表中强制执行单一数据库查询

为了发送主/细型报表的单一数据库查询,需要以某种方式编写报表并更改 CQEConfig.xml 文件的配置。以下各节将提供实现这两项操作所需要的步骤。

向 CQEConfig.xml 文件添加配置参数

此技术需要在执行数据访问的所有 IBM Cognos BI 应用服务器上为 CQEConfig.xml 文件添加 RequestHintLocalCacheHasHigherPriority 参数。要添加此参数:

  1. 在 <install_directory>\configuration 目录中找到 CQEConfig.xml.sample 文件位置。
  2. 复制此文件并将它重命名为 CQEConfig.xml。
  3. 使用文本编辑器打开 CQEConfig.xml 文件。
  4. 在 CQEConfig.xml 文件内,找到文本 <section name="QueryEngine">,并在 <section name="QueryEngine"> 一节下方的新行中添加 <entry name="RequestHintLocalCacheHasHigherPriority" value="0"/>
    完成此操作后,该条目应该显示如下:
    		<section name="QueryEngine">
    		<entry name="RequestHintLocalCacheHasHigherPriority" value="0"/>
    		…
  5. 保存对该文件的更改。
  6. 对该文件的更改将在 IBM Cognos 服务停止后并重新启动时生效。

调整 IBM Cognos Report Studio 主/细型报表

此技术也要求以某种方式编写主/细型报表。这一节将使用第 2 节中引用的报表作为起点,并提供所需的更改。IBM Cognos 报表规范已作为附录 A 添加到此文档中。

  1. 在 IBM Cognos Report Studio Query Explorer 中,从可用的 Toolbox 项中,拖入两个独立的 Query 对象。
  2. 将其中一个 Query 对象重命名为 Master,并将另一个重命名为 Detail。
    操作完成之后,IBM Cognos Report Studio Query Explorer 应该拥有 3 个 Query 对象:一个用于运行报表的原始数据项的 BaseQuery,以及其他两个分别名为 Master 和 Detail 的 Query 对象。
    图 3 显示 3 个 Query 对象的 IBM Cognos Report Studio Query Explorer
    图 3 显示 3 个 Query 对象的 IBM Cognos Report Studio Query Explorer
  3. 要创建子查询,将 BaseQuery 对象拖到 Master Query 和 Detail Query 对象的右侧。
    这个拖动操作将生成一个从 BaseQuery 对象到 Master 和 Detail 对象的箭头,表示正使用 BaseQuery 填充其他 Query 对象。如下屏幕截图所示。
    图 4 IBM Cognos Report Studio 显示:BaseQuery 为一个子查询
    图 4 IBM Cognos Report Studio 显示:BaseQuery 为一个子查询
  4. 双击 Master Query 对象。
  5. 从左侧的 Insertable Objects 窗格中,选择 BaseQuery Order 方法对象并将其拖入 Data Items 窗格。
  6. 在屏幕中央,单击 Query Explorer 并重新选择 Master Query 对象。
  7. 在左下侧的 Properties 窗格中,找到 Use Local Cache 属性并将其设置为 yes。
  8. 在屏幕中央,单击 Query Explorer 并重新选择 Detail Query 对象。
  9. 从左侧的 Insertable Objects 窗格中,选择所有 BaseQuery 对象并将它们拖到 Data Items 窗格中。
  10. 在屏幕中央,单击 Query Explorer 并重新选择 Detail Query 对象。
  11. 在左下侧的 Properties 窗格中,找到 Use Local Cache 属性并将其设置为 yes。
  12. 在左下侧的 Properties 窗格中,找到 Use SQL Parameters 属性并将它设置为 Literal。
  13. 在屏幕中央,单击 Page Explorer 并在 Report Pages 文件夹下重新选择 Page1。
  14. 选择 List 对象,在左下侧的 List Properties 中,将 Query 从 BaseQuery 切换到 Master。下图显示了所选的 List 对象,以及左下侧 List Properties 窗格中的 Query 属性从 BaseQuery 查询更改为 Master 查询。
    图 5 显示 List Properties 的 IBM Cognos Report Studio
    图 5 显示 List Properties 的 IBM Cognos Report Studio
  15. 选择交叉表对象,在左下侧的 Crosstab Properties 中,将 Query 从 BaseQuery 切换到 Detail。下图显示了所选的 Crosstab 对象,以及左下侧 Crosstab Properties 窗格中的 Query 属性从 BaseQuery 更改为 Detail 查询。
    图 6 显示 Crosstab Properties 的 IBM Cognos Report Studio
    图 6 显示 Crosstab Properties 的 IBM Cognos Report Studio
    进行了这些更改后执行报表,查询数据库上的结构化查询语言 (SQL) 跟踪现会显示,已向查询数据库发送了一个单一的 SQL 语句,即使 Master 查询拥有多个 Order 方法。
    最终的 IBM Cognos Report Studio 报表规范作为附录 B 添加到了此文档中,仅供参考。

附录 A:具有多个数据库查询的主/细报表规范

<report xmlns="http://developer.cognos.com/schemas/report/6.0/" expressionLocale="en-ca">
        <modelPath>/content/folder[@name='Samples']/folder[@name='Models']
          /package[@name='GO Sales (query)']/model[@name='model']</modelPath>
        <drillBehavior modelBasedDrillThru="true"/>
        <queries>
          <query name="Query1">
            <source>
              <model/>
            </source>
            <selection><dataItem name="Quantity" aggregate="total"><expression>
              [Sales (query)].[Sales].[Quantity]</expression></dataItem>
              <dataItem name="Order method" aggregate="none" rollupAggregate="none">
              <expression>[Sales (query)].[Order method].[Order method]</expression>
              </dataItem><dataItem name="Product line" aggregate="none" 
              rollupAggregate="none"><expression>[Sales (query)].[Product].
              [Product line]</expression></dataItem>
              <dataItem name="Year" aggregate="none" rollupAggregate="none"><expression>
              [Sales (query)].[Time dimension].[Year]</expression></dataItem></selection>
          </query>
        </queries>
        <layouts>
          <layout>
            <reportPages>
              <page name="Page1"><style><defaultStyles><defaultStyle refStyle="pg"/>
                </defaultStyles></style>
                <pageBody><style><defaultStyles><defaultStyle refStyle="pb"/>
                  </defaultStyles></style>
                  <contents>
                    <list showColumnTitles="hide" refQuery="Query1">
      <listColumns>
        <listColumn>
          <listColumnTitle>
            <contents/>
          </listColumnTitle>
          <listColumnBody>
            <contents><crosstab refQuery="Query1" horizontalPagination="true"
              name="Crosstab1">
                      <crosstabCorner><style><defaultStyles><defaultStyle refStyle="xm"/>
                        </defaultStyles></style><contents><textItem><dataSource>
                        <dataItemLabel refDataItem="Quantity"/></dataSource></textItem>
                        </contents></crosstabCorner>
                      
                      
                      <style>
                        <defaultStyles>
                          <defaultStyle refStyle="xt"/>
                        </defaultStyles>
                        <CSS value="border-collapse:collapse"/>
                      </style>
                    <defaultMeasure refDataItem="Quantity"/><crosstabFactCell><contents>
                      <textItem><dataSource><cellValue/></dataSource></textItem>
                      </contents><style><defaultStyles><defaultStyle refStyle="mv"/>
                      </defaultStyles></style></crosstabFactCell><crosstabRows>
                      <crosstabNode><crosstabNodeMembers><crosstabNodeMember 
                      refDataItem="Product line" edgeLocation="e2"><style><defaultStyles>
                      <defaultStyle refStyle="ml"/></defaultStyles></style><contents>
                      <textItem><dataSource><memberCaption/></dataSource>
                      </textItem></contents></crosstabNodeMember></crosstabNodeMembers>
                      </crosstabNode></crosstabRows><crosstabColumns><crosstabNode>
                      <crosstabNodeMembers><crosstabNodeMember refDataItem="Year" 
                      edgeLocation="e3"><style><defaultStyles>
                      <defaultStyle refStyle="ml"/></defaultStyles></style><contents>
                      <textItem><dataSource><memberCaption/></dataSource>
                      </textItem></contents></crosstabNodeMember></crosstabNodeMembers>
                      </crosstabNode></crosstabColumns><masterDetailLinks>
                      <masterDetailLink><masterContext><dataItemContext 
                      refDataItem="Order method"/></masterContext><detailContext> 
                      <dataItemContext refDataItem="Order method"/></detailContext>
                      </masterDetailLink></masterDetailLinks></crosstab></contents>
            <style>
              <defaultStyles>
                <defaultStyle refStyle="sb"/>
              </defaultStyles>
            </style>
          </listColumnBody>
        </listColumn>
      </listColumns>
      
      
      
      <style>
        <CSS value="border-collapse:collapse; width:100%"/>
        <defaultStyles>
          <defaultStyle refStyle="sc"/>
        </defaultStyles>
      </style>
    <listGroups><listGroup refDataItem="Order method"><listHeader><listRows><listRow>
      <rowCells><rowCell><contents><textItem><dataSource><dataItemValue 
      refDataItem="Order method"/></dataSource></textItem></contents><style>
      <defaultStyles><defaultStyle refStyle="sh"/></defaultStyles></style></rowCell>
      </rowCells></listRow></listRows></listHeader></listGroup>
      </listGroups></list>
                  </contents>
                </pageBody>
                <pageHeader>
                  <contents>
                    <block><style><defaultStyles><defaultStyle refStyle="ta"/>
                      </defaultStyles></style>
                      <contents>
                        <textItem><style><defaultStyles><defaultStyle refStyle="tt"/>
                          </defaultStyles></style>
                          <dataSource>
                            <staticValue/>
                          </dataSource>
                        </textItem>
                      </contents>
                    </block>
                  </contents>
                  <style>
                    <defaultStyles>
                      <defaultStyle refStyle="ph"/>
                    </defaultStyles>
                    <CSS value="padding-bottom:10px"/>
                  </style>
                </pageHeader>
                <pageFooter>
                  <contents>
                    <table>
                      <tableRows>
                        <tableRow>
                          <tableCells>
                            <tableCell>
                              <contents>
                                <date>
                                  <style>
                                    <dataFormat>
                                      <dateFormat/>
                                    </dataFormat>
                                  </style>
                                </date>
                              </contents>
                              <style>
                                <CSS value="vertical-align:top;
                                  text-align:left;width:25%"/>
                              </style>
                            </tableCell>
                            <tableCell>
                              <contents>
                                <pageNumber/>
                              </contents>
                              <style>
                                <CSS value="vertical-align:top;
                                  text-align:center;width:50%"/>
                              </style>
                            </tableCell>
                            <tableCell>
                              <contents>
                                <time>
                                  <style>
                                    <dataFormat>
                                      <timeFormat/>
                                    </dataFormat>
                                  </style>
                                </time>
                              </contents>
                              <style>
                                <CSS value="vertical-align:top;
                                  text-align:right;width:25%"/>
                              </style>
                            </tableCell>
                          </tableCells>
                        </tableRow>
                      </tableRows>
                      <style>
                        <defaultStyles>
                          <defaultStyle refStyle="tb"/>
                        </defaultStyles>
                        <CSS value="border-collapse:collapse;width:100%"/>
                      </style>
                    </table>
                  </contents>
                  <style>
                    <defaultStyles>
                      <defaultStyle refStyle="pf"/>
                    </defaultStyles>
                    <CSS value="padding-top:10px"/>
                  </style>
                </pageFooter>
              </page>
            </reportPages>
          </layout>
        </layouts>
      <XMLAttributes><XMLAttribute name="RS_CreateExtendedDataItems" value="true"
        output="no"/><XMLAttribute name="listSeparator" value="," output="no"/>
        </XMLAttributes></report>

附录 B:具有单一数据库查询的主/细报表规范

<report xmlns="http://developer.cognos.com/schemas/report/6.0/" expressionLocale="en-ca">
        <modelPath>/content/folder[@name='Samples']/folder[@name='Models']
          /package[@name='GO Sales (query)']/model[@name='model']</modelPath>
        <drillBehavior modelBasedDrillThru="true"/>
        <queries>
          <query name="BaseQuery">
            <source>
              <model/>
            </source>
            <selection><dataItem name="Quantity" aggregate="total"><expression>
              [Sales (query)].[Sales].[Quantity]</expression></dataItem>
              <dataItem name="Order method" aggregate="none" rollupAggregate="none">
              <expression>[Sales (query)].[Order method].[Order method]</expression>
              </dataItem><dataItem name="Product line" aggregate="none" 
              rollupAggregate="none"><expression>[Sales (query)].[Product].[Product line]
              </expression></dataItem><dataItem name="Year" aggregate="none" 
              rollupAggregate="none"><expression>[Sales (query)].[Time dimension].[Year]
              </expression></dataItem></selection>
          </query>
        <query name="Master">
      <source>
        
      <queryRef refQuery="BaseQuery"/></source>
      <selection><dataItem name="Order method"><expression>[BaseQuery].[Order method]
        </expression></dataItem></selection>
    <queryHints><localCache value="true"/></queryHints></query><query name="Detail">
      <source>
        
      <queryRef refQuery="BaseQuery"/></source>
      <selection><dataItem name="Quantity"><expression>[BaseQuery].[Quantity]
        </expression></dataItem><dataItem name="Year"><expression>[BaseQuery].[Year]
        </expression></dataItem><dataItem name="Order method"><expression>
        [BaseQuery].[Order method]</expression></dataItem><dataItem name="Product line">
        <expression>[BaseQuery].[Product line]</expression></dataItem></selection>
    <queryHints><localCache value="true"/><useSQLParameters value="literal"/>
      </queryHints></query></queries>
        <layouts>
          <layout>
            <reportPages>
              <page name="Page1"><style><defaultStyles><defaultStyle refStyle="pg"/>
                </defaultStyles></style>
                <pageBody><style><defaultStyles><defaultStyle refStyle="pb"/>
                  </defaultStyles></style>
                  <contents>
                    <list showColumnTitles="hide" refQuery="Master">
      <listColumns>
        <listColumn>
          <listColumnTitle>
            <contents/>
          </listColumnTitle>
          <listColumnBody>
            <contents><crosstab horizontalPagination="true" name="Crosstab1"
              refQuery="Detail">
                      <crosstabCorner><style><defaultStyles><defaultStyle refStyle="xm"/>
                        </defaultStyles></style><contents><textItem><dataSource>
                        <dataItemLabel refDataItem="Quantity"/></dataSource></textItem>
                        </contents></crosstabCorner>
                      
                      
                      <style>
                        <defaultStyles>
                          <defaultStyle refStyle="xt"/>
                        </defaultStyles>
                        <CSS value="border-collapse:collapse"/>
                      </style>
                    <defaultMeasure refDataItem="Quantity"/><crosstabFactCell><contents>
                      <textItem><dataSource><cellValue/></dataSource></textItem>
                      </contents><style><defaultStyles><defaultStyle refStyle="mv"/>
                      </defaultStyles></style></crosstabFactCell><crosstabRows>
                      <crosstabNode><crosstabNodeMembers><crosstabNodeMember
                      refDataItem="Product line" edgeLocation="e2"><style><defaultStyles>
                      <defaultStyle refStyle="ml"/></defaultStyles></style><contents>
                      <textItem><dataSource><memberCaption/></dataSource></textItem>
                      </contents></crosstabNodeMember></crosstabNodeMembers>
                      </crosstabNode></crosstabRows><crosstabColumns><crosstabNode>
                      <crosstabNodeMembers><crosstabNodeMember refDataItem="Year" 
                      edgeLocation="e3"><style><defaultStyles><defaultStyle 
                      refStyle="ml"/></defaultStyles></style><contents><textItem>
                      <dataSource><memberCaption/></dataSource></textItem>
                      </contents></crosstabNodeMember></crosstabNodeMembers>
                      </crosstabNode></crosstabColumns><masterDetailLinks>
                      <masterDetailLink><masterContext><dataItemContext 
                      refDataItem="Order method"/></masterContext><detailContext>
                      <dataItemContext refDataItem="Order method"/></detailContext>
                      </masterDetailLink></masterDetailLinks></crosstab></contents>
            <style>
              <defaultStyles>
                <defaultStyle refStyle="sb"/>
              </defaultStyles>
            </style>
          </listColumnBody>
        </listColumn>
      </listColumns>
      
      
      
      <style>
        <CSS value="border-collapse:collapse; width:100%"/>
        <defaultStyles>
          <defaultStyle refStyle="sc"/>
        </defaultStyles>
      </style>
    <listGroups><listGroup refDataItem="Order method"><listHeader><listRows><listRow>
      <rowCells><rowCell><contents><textItem><dataSource><dataItemValue
      refDataItem="Order method"/></dataSource></textItem></contents><style>
      <defaultStyles><defaultStyle refStyle="sh"/></defaultStyles></style></rowCell>
      </rowCells></listRow></listRows></listHeader></listGroup></listGroups></list>
                  </contents>
                </pageBody>
                <pageHeader>
                  <contents>
                    <block><style><defaultStyles><defaultStyle refStyle="ta"/>
                      </defaultStyles></style>
                      <contents>
                        <textItem><style><defaultStyles><defaultStyle refStyle="tt"/>
                          </defaultStyles></style>
                          <dataSource>
                            <staticValue/>
                          </dataSource>
                        </textItem>
                      </contents>
                    </block>
                  </contents>
                  <style>
                    <defaultStyles>
                      <defaultStyle refStyle="ph"/>
                    </defaultStyles>
                    <CSS value="padding-bottom:10px"/>
                  </style>
                </pageHeader>
                <pageFooter>
                  <contents>
                    <table>
                      <tableRows>
                        <tableRow>
                          <tableCells>
                            <tableCell>
                              <contents>
                                <date>
                                  <style>
                                    <dataFormat>
                                      <dateFormat/>
                                    </dataFormat>
                                  </style>
                                </date>
                              </contents>
                              <style>
                                <CSS value="vertical-align:top;
                                  text-align:left;width:25%"/>
                              </style>
                            </tableCell>
                            <tableCell>
                              <contents>
                                <pageNumber/>
                              </contents>
                              <style>
                                <CSS value="vertical-align:top;
                                  text-align:center;width:50%"/>
                              </style>
                            </tableCell>
                            <tableCell>
                              <contents>
                                <time>
                                  <style>
                                    <dataFormat>
                                      <timeFormat/>
                                    </dataFormat>
                                  </style>
                                </time>
                              </contents>
                              <style>
                                <CSS value="vertical-align:top;
                                  text-align:right;width:25%"/>
                              </style>
                            </tableCell>
                          </tableCells>
                        </tableRow>
                      </tableRows>
                      <style>
                        <defaultStyles>
                          <defaultStyle refStyle="tb"/>
                        </defaultStyles>
                        <CSS value="border-collapse:collapse;width:100%"/>
                      </style>
                    </table>
                  </contents>
                  <style>
                    <defaultStyles>
                      <defaultStyle refStyle="pf"/>
                    </defaultStyles>
                    <CSS value="padding-top:10px"/>
                  </style>
                </pageFooter>
              </page>
            </reportPages>
          </layout>
        </layouts>
      <XMLAttributes><XMLAttribute name="RS_CreateExtendedDataItems" value="true"
        output="no"/><XMLAttribute name="listSeparator" value="," output="no"/>
        </XMLAttributes></report>

参考资料

学习

获得产品和技术

讨论

  • 参与 developerWorks 博客 并加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management
ArticleID=810388
ArticleTitle=IBM Cognos 最佳实践: 改进 IBM Cognos Report Studio 的主/细报表性能
publish-date=05102012