使用saiku的过程中发现一个重要问题,速度慢!下面是跟踪和优化过程

一、首先抓包,发现ajax请求:http://l-tdata2.tkt.cn6.qunar.com:8080/saiku/rest/saiku/api/query/execute

里面的参数不少,下面是截屏

二、看日志:发现了mdx语句

WITH
SET [~ROWS_create_date_create_date] AS
{[create_date].[create_date].[--]}
SET [~ROWS_dimPartner_dimPartner] AS
Hierarchize({{[dimPartner].[dimPartner].[All dimPartners]}, {[dimPartner].[dimPartner].[name].Members}})
SET [~ROWS_in_track_in_track] AS
{[in_track].[in_track].[All in_tracks]}
SET [~ROWS_product_product] AS
{[product].[product].[All products]}
SET [~ROWS_self_self] AS
{[self].[self].[All selfs]}
SET [~ROWS_sight_sight] AS
{[sight].[sight].[All sights]}
SET [~ROWS_ticket_type_ticket_type] AS
{[ticket_type].[ticket_type].[All ticket_types]}
SET [~ROWS_order_status_order_status] AS
{[order_status].[order_status].[All order_statuss]}
SET [~ROWS_refund_status_refund_status] AS
{[refund_status].[refund_status].[All refund_statuss]}
SELECT
NON EMPTY {[Measures].[money], [Measures].[quantity], [Measures].[qunar_income], [Measures].[order_num]} ON COLUMNS,
NON EMPTY Order(NonEmptyCrossJoin([~ROWS_create_date_create_date], NonEmptyCrossJoin([~ROWS_dimPartner_dimPartner], NonEmptyCrossJoin([~ROWS_in_track_in_track], NonEmptyCrossJoin([~ROWS_product_product], NonEmptyCrossJoin([~ROWS_self_self], NonEmptyCrossJoin([~ROWS_sight_sight], NonEmptyCrossJoin([~ROWS_ticket_type_ticket_type], NonEmptyCrossJoin([~ROWS_order_status_order_status], [~ROWS_refund_status_refund_status])))))))), [Measures].[money], BDESC) ON ROWS
FROM [com_order_detail_cube]
-- ::, INFO [org.saiku.datasources.connection.SaikuOlapConnection] Clearing cache
-- ::, WARN [mondrian.rolap.RolapSchema] Model is in legacy format
-- ::, INFO [org.saiku.datasources.connection.SaikuOlapConnection] Catalogs:
-- ::, DEBUG [org.saiku.service.olap.ThinQueryService] Query End
-- ::, INFO [org.saiku.service.olap.ThinQueryService] RUN#: Size: / Execute: 190420ms Format: 0ms Totals: 0ms Total: 190420ms

观察日志,发现前端一直执行不返回。分析主要原因是执行mdx需要很长时间,190秒

3、找代码:org.saiku.web.rest.resources.Query2Resource的execute方法

继续追踪代码:org.saiku.service.olap.ThinQueryService的execute方法()。下面是核心重点:

    private CellDataSet execute(ThinQuery tq, ICellSetFormatter formatter) {
try { Long start = (new Date()).getTime();
log.debug("Query Start");
CellSet cellSet = executeInternalQuery(tq); //这是执行mdx语句的地方,需要较长时间
log.debug("Query End");
String runId = "RUN#:" + ID_GENERATOR.get();
Long exec = (new Date()).getTime(); CellDataSet result = OlapResultSetUtil.cellSet2Matrix(cellSet,formatter);
Long format = (new Date()).getTime(); if (ThinQuery.Type.QUERYMODEL.equals(tq.getType()) && formatter instanceof FlattenedCellSetFormatter && tq.hasAggregators()) {
calculateTotals(tq, result, cellSet, formatter);
}
Long totals = (new Date()).getTime();
log.info(runId + "\tSize: " + result.getWidth() + "/" + result.getHeight() + "\tExecute:\t" + (exec - start)
+ "ms\tFormat:\t" + (format - exec) + "ms\tTotals:\t" + (totals - format) + "ms\t Total: " + (totals - start) + "ms"); result.setRuntime(new Double(format - start).intValue());
return result;
} catch (Exception | Error e) {
throw new SaikuServiceException("Can't execute query: " + tq.getName(),e);
}
}

4、查看数据执行的sql,看看为什么执行的很慢

4.1 选择情况

首先任何的筛选都是对立方体内的字段进行全表的扫描,比如我的立方体对应的数据表是:com_order_detail_view,时间对应的字段是create_date,那么选择时间的时候,捕获执行的sql如下:

 select "com_order_detail_view"."create_date" as "c0" from "com_order_detail_view" as "com_order_detail_view" group by "com_order
_detail_view"."create_date" order by "com_order_detail_view"."create_date" ASC NULLS LAST

发现根本没有where条件。好吧,这个可以理解!

4.2 执行情况

筛选的时候,为了提升效率,选择了一个日期,并且只是选择了name字段作为区分。执行时间:190s

抓取的sql如下:

4.2.1

select "dim_partner"."name" as "c0", sum("com_order_detail_view"."money") as "m0", sum("com_order_detail_view"."quantity") as "m1", sum("com_order_detail_view"."qunar_income") as "m2", count(distinct "com_order_detail_view"."display_id") as "m3" from "com_order_detail_view" as "com_order_detail_view", "dim_partner" as "dim_partner" where "com_order_detail_view"."partner" = "dim_partner"."code" group by "dim_partner"."name"

4.2.2

 select sum("com_order_detail_view"."money") as "m0", sum("com_order_detail_view"."quantity") as "m1", sum("com_order_detail_view"."qunar_income") as "m2", count(distinct "com_order_detail_view"."display_id") as "m3" from "com_order_detail_view" as "com_order_detail_view"

没有发现where条件。猜测可能是选择日期没有在过滤条件里面,所以全表扫描,那么将日期放入过滤条件,mdx被修改为:

WITH
SET [~FILTER] AS
{[create_date].[create_date].[--]}
SET [~ROWS_dimPartner_dimPartner] AS
Hierarchize({{[dimPartner].[dimPartner].[All dimPartners]}, {[dimPartner].[dimPartner].[name].Members}})
SET [~ROWS_in_track_in_track] AS
{[in_track].[in_track].[All in_tracks]}
SET [~ROWS_product_product] AS
{[product].[product].[All products]}
SET [~ROWS_self_self] AS
{[self].[self].[All selfs]}
SET [~ROWS_sight_sight] AS
{[sight].[sight].[All sights]}
SET [~ROWS_ticket_type_ticket_type] AS
{[ticket_type].[ticket_type].[All ticket_types]}
SET [~ROWS_order_status_order_status] AS
{[order_status].[order_status].[All order_statuss]}
SET [~ROWS_refund_status_refund_status] AS
{[refund_status].[refund_status].[All refund_statuss]}
SELECT
NON EMPTY {[Measures].[money], [Measures].[quantity], [Measures].[qunar_income], [Measures].[order_num]} ON COLUMNS,
NON EMPTY Order(NonEmptyCrossJoin([~ROWS_dimPartner_dimPartner], NonEmptyCrossJoin([~ROWS_in_track_in_track], NonEmptyCrossJoin([~ROWS_product_product], NonEmptyCrossJoin([~ROWS_self_self], NonEmptyCrossJoin([~ROWS_sight_sight], NonEmptyCrossJoin([~ROWS_ticket_type_ticket_type], NonEmptyCrossJoin([~ROWS_order_status_order_status], [~ROWS_refund_status_refund_status]))))))), [Measures].[money], BDESC) ON ROWS
FROM [com_order_detail_cube]
WHERE [~FILTER]
-- ::, DEBUG [org.saiku.service.olap.ThinQueryService] Query End
-- ::, INFO [org.saiku.service.olap.ThinQueryService] RUN#: Size: / Execute: 20679ms Format: 1ms Totals: 0ms Total: 20680ms

发现有了效果,执行时间:20s。下面是抓取的sql

4.2.3

select "com_order_detail_view"."create_date" as "c0", "dim_partner"."name" as "c1", sum("com_order_detail_view"."money") as "m0", sum("com_order_detail_view"."quantity") as "m1", sum("com_order_detail_view"."qunar_income") as "m2", count(distinct "com_order_detail_view"."display_id") as "m3" from "com_order_detail_view" as "com_order_detail_view", "dim_partner" as "dim_partner" where "com_order_detail_view"."create_date" = DATE '2016-04-01' and "com_order_detail_view"."partner" = "dim_partner"."code" group by "com_order_detail_view"."create_date", "dim_partner"."name"

4.2.4

select "com_order_detail_view"."create_date" as "c0", sum("com_order_detail_view"."money") as "m0", sum("com_order_detail_view"."quantity") as "m1", sum("com_order_detail_view"."qunar_income") as "m2", count(distinct "com_order_detail_view"."display_id") as "m3" from "com_order_detail_view" as "com_order_detail_view" where "com_order_detail_view"."create_date" = DATE '2016-04-01' group by "com_order_detail_view"."create_date"

总结:使用saiku的时候,将时间条件放在《行》或者《列》里面,基本不起作用。最好放入在《过滤》里面

saiku执行速度慢的更多相关文章

  1. saiku执行速度优化二

    上一篇文章介绍了添加filter可以加快查询速度.下面继续分析: 下面这个MDX语句: WITH SET [~FILTER] AS {[create_date].[create_date].[--]} ...

  2. .NET 的 Debug 和 Release build 对执行速度的影响

    这篇文章发布于我的 github 博客:原文 在真正开始讨论之前先定义一下 Scope. 本文讨论的范围限于执行速度,内存占用什么的不在评估的范围之内. 本文不讨论算法:编译器带来的优化基本上属于底层 ...

  3. JavaScript代码优化(下载时间和执行速度优化)

    JavaScript代码的速度被分成两部分:下载时间和执行速度. 下载时间 Web浏览器下载的是js源码,因此所有长变量名和注释都回包含在内.这个因素会增加下载时间.1160是一个TCP-IP包中的字 ...

  4. ansible系列5-开启加速 Ansible 执行速度的功能

    SSH pipelining 是一个加速 Ansible 执行速度的简单方法.ssh pipelining 默认是关闭,之所以默认关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选 ...

  5. php中各种hash算法的执行速度比较

    更多内容推荐微信公众号,欢迎关注: PHP中的Hash函数很多,像MD4.MD5.SHA-1.SHA-256.SHA-384.SHA-512等我们比较常见,那么各个哈希的执行速度呢? $algos = ...

  6. 采用Psyco实现python执行速度提高到与编译语言一样的水平

    本文实例讲述了采用Psyco实现python执行速度提高到与编译语言一样的水平的方法,分享给大家供大家参考.具体实现方法如下: 一.安装Psyco很简单,它有两种安装方式,一种是源码方式,一种是二进制 ...

  7. 【知识点整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行速度的比较

    [知识点整理]Oracle中NOLOGGING.APPEND.ARCHIVE和PARALLEL下,REDO.UNDO和执行速度的比较 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 ...

  8. 效率包括了代码的GC 大小与内存大小,执行速度等等。其中执行速度不是关注 的重点

    效率包括了代码的GC 大小与内存大小,执行速度等等.其中执行速度不是关注的重点

  9. 嫌Excel VBA执行速度慢,这些建议你一定要看

    Excel是办公利器,这无需多言.尤其在办公室,Excel用的熟练与否,会的Excel知识点多不多,很大程度上决定了你工作是否高效,能否按时打卡下班.可我们也时常听到这样的吐槽:Excel好是好,可就 ...

随机推荐

  1. NUnit-Console 命令行选项详解

    本文为 Dennis Gao 原创或翻译技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. NUnit-Console 命令行选项 NUnit-Console 命令行选项列表 指定运行哪 ...

  2. 选择哪种方式进行SharePoint的备份

    关于SharePoint的备份还原功能,大家可能都有所了解.但是SharePoint一共有多少种备份方式呢,哪种备份方式是更适合你的呢,本文主要为大家梳理,并且深入的研究一下常见的几种备份方式,以便大 ...

  3. iOS YSDropdownMagnify 下拉放大,向上导航显示

    要实现的效果如上.在实际开发中,我们会使用到三种方式来实现. 通过隐藏导航栏,自定义导航View 改变原生导航栏背景透明 原生导航栏通过添加背景图片改变 个人是比较喜欢第二种. github下载地址: ...

  4. 深入理解 CSS 的 :before 和 :after 选择器(制作select下拉列表美化插件)

    原文链接:http://www.cnblogs.com/LY-leo/p/5765598.html 对于 :before 和 :after 选择器,大家并不陌生,但是很少有人会主动去用它们.先解释下它 ...

  5. Atitit.信息论原理概论attilax总结

    Atitit.信息论原理概论attilax总结 1. <信息论基础(原书第2版)>((美)科弗(Cover...)[简介_书评_在线阅读] - 当当图书.html1 2. <信息论- ...

  6. [推荐]PaaS技术知识贴

    [推荐]PaaS技术知识贴 云计算PaaS技术与应用 http://wenku.baidu.com/view/08f77eefaeaad1f346933f20?fr=prin大型WEB网站架构深入分析 ...

  7. C#中的串口通信

    关于串行接口 串行接口(Serial port)又称“串口”,主要用于串行式逐位数据传输.常见的有一般电脑应用的RS-232(使用 25 针或 9 针连接器)和工业电脑应用的半双工RS-485与全双工 ...

  8. What is /proc/slabinfo?

    /proc/slabinfo gives information about memory usage on the slab level. Linux kernels uses slab pools ...

  9. AD8275 Driver Amplifiers For Analog-To-Digital Converters

    Driver Amplifiers For Analog-To-Digital Converters What amplifiers are used to drive analog-to-digit ...

  10. 关于iphone6安装了727个应用后,更新app 导致一些app无法更新,无法删除,重启后消失,但是却还是占用空间的解决办法

    我的iphone6 苹果手机,64GB的,存储空间最近一直很吃紧,很捉急,昨天,终于下定决心 解决下这个问题. 由于 空间大,我又随便安装许多APP,现在有727个app,常用的其实就是那个几十个而已 ...