之前同事发过一个语句,实现的功能比較简单,相似group by的分组计数功能,由于where条件有like,又无法用group by来实现。
SELECT a.N0,b.N1,c.N2,d.N3,e.N4,f.N5,g.N6,h.N7,i.N8,j.N9 from
(select count(*) N0 from tbl_loginfo_20141110 where keyrecord like '0%' or keyrecord like 'GJ_0%') a,
(select count(*) N1 from tbl_loginfo_20141110 where keyrecord like '1%' or keyrecord like 'GJ_1%') b,
(select count(*) N2 from tbl_loginfo_20141110 where keyrecord like '2%' or keyrecord like 'GJ_2%') c,
(select count(*) N3 from tbl_loginfo_20141110 where keyrecord like '3%' or keyrecord like 'GJ_3%') d,
(select count(*) N4 from tbl_loginfo_20141110 where keyrecord like '4%' or keyrecord like 'GJ_4%') e,
(select count(*) N5 from tbl_loginfo_20141110 where keyrecord like '5%' or keyrecord like 'GJ_5%') f,
(select count(*) N6 from tbl_loginfo_20141110 where keyrecord like '6%' or keyrecord like 'GJ_6%') g,
(select count(*) N7 from tbl_loginfo_20141110 where keyrecord like '7%' or keyrecord like 'GJ_7%') h,
(select count(*) N8 from tbl_loginfo_20141110 where keyrecord like '8%' or keyrecord like 'GJ_8%') i,
(select count(*) N9 from tbl_loginfo_20141110 where keyrecord like '9%' or keyrecord like 'GJ_9%') j; 为了了解语句的性能,我做了例如以下相似的測试:
select * from v$version; --Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
drop table a;
create table a as select * from dba_objects where rownum<=50000;
begin
for x in 1..6 loop
insert into a select * from a;
end loop;
commit;
end; select count(*) from a; --3200000
select bytes/1024/1024 from user_segments where segment_name='A'; --357M alter system flush shared_pool;
alter system flush buffer_cache; SELECT a.N0,b.N1,c.N2,d.N3,e.N4,f.N5,g.N6,h.N7,i.N8,j.N9 from
(select count(*) N0 from a where object_name like 'A%' or object_name like 'V%') a,
(select count(*) N1 from a where object_name like 'B%' or object_name like 'V%') b,
(select count(*) N2 from a where object_name like 'C%' or object_name like 'V%') c,
(select count(*) N3 from a where object_name like 'D%' or object_name like 'V%') d,
(select count(*) N4 from a where object_name like 'E%' or object_name like 'V%') e,
(select count(*) N5 from a where object_name like 'F%' or object_name like 'V%') f,
(select count(*) N6 from a where object_name like 'G%' or object_name like 'V%') g,
(select count(*) N7 from a where object_name like 'H%' or object_name like 'V%') h,
(select count(*) N8 from a where object_name like 'I%' or object_name like 'V%') i,
(select count(*) N9 from a where object_name like 'J%' or object_name like 'V%') j;
--58s
alter system flush shared_pool;
alter system flush buffer_cache; --改写后
select
sum(case when object_name like 'A%' or object_name like 'V%' then 1 else 0 end) N0,
sum(case when object_name like 'B%' or object_name like 'V%' then 1 else 0 end) N1,
sum(case when object_name like 'C%' or object_name like 'V%' then 1 else 0 end) N2,
sum(case when object_name like 'D%' or object_name like 'V%' then 1 else 0 end) N3,
sum(case when object_name like 'E%' or object_name like 'V%' then 1 else 0 end) N4,
sum(case when object_name like 'F%' or object_name like 'V%' then 1 else 0 end) N5,
sum(case when object_name like 'G%' or object_name like 'V%' then 1 else 0 end) N6,
sum(case when object_name like 'H%' or object_name like 'V%' then 1 else 0 end) N7,
sum(case when object_name like 'I%' or object_name like 'V%' then 1 else 0 end) N8,
sum(case when object_name like 'J%' or object_name like 'V%' then 1 else 0 end) N9
from a; --19s --对照运行计划:
--前者运行计划:
SQL> explain plan for
2 SELECT a.N0,b.N1,c.N2,d.N3,e.N4,f.N5,g.N6,h.N7,i.N8,j.N9 from
3 (select count(*) N0 from a where object_name like 'A%' or object_name like 'V%') a,
4 (select count(*) N1 from a where object_name like 'B%' or object_name like 'V%') b,
5 (select count(*) N2 from a where object_name like 'C%' or object_name like 'V%') c,
6 (select count(*) N3 from a where object_name like 'D%' or object_name like 'V%') d,
7 (select count(*) N4 from a where object_name like 'E%' or object_name like 'V%') e,
8 (select count(*) N5 from a where object_name like 'F%' or object_name like 'V%') f,
9 (select count(*) N6 from a where object_name like 'G%' or object_name like 'V%') g,
10 (select count(*) N7 from a where object_name like 'H%' or object_name like 'V%') h,
11 (select count(*) N8 from a where object_name like 'I%' or object_name like 'V%') i,
12 (select count(*) N9 from a where object_name like 'J%' or object_name like 'V%') j; Explained. Elapsed: 00:00:00.15
SQL> @getplan
'general,outline,starts' Enter value for plan type: PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------
Plan hash value: 2527411742 -------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 130 | 123K (1)| 00:24:46 |
| 1 | NESTED LOOPS | | 1 | 130 | 123K (1)| 00:24:46 |
| 2 | NESTED LOOPS | | 1 | 117 | 111K (1)| 00:22:17 |
| 3 | NESTED LOOPS | | 1 | 104 | 99032 (1)| 00:19:49 |
| 4 | NESTED LOOPS | | 1 | 91 | 86653 (1)| 00:17:20 |
| 5 | NESTED LOOPS | | 1 | 78 | 74274 (1)| 00:14:52 |
| 6 | NESTED LOOPS | | 1 | 65 | 61895 (1)| 00:12:23 |
| 7 | NESTED LOOPS | | 1 | 52 | 49516 (1)| 00:09:55 |
| 8 | NESTED LOOPS | | 1 | 39 | 37137 (1)| 00:07:26 |
| 9 | NESTED LOOPS | | 1 | 26 | 24758 (1)| 00:04:58 |
| 10 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 11 | SORT AGGREGATE | | 1 | 66 | | |
|* 12 | TABLE ACCESS FULL| A | 91587 | 5903K| 12379 (1)| 00:02:29 |
| 13 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 14 | SORT AGGREGATE | | 1 | 66 | | |
|* 15 | TABLE ACCESS FULL| A | 137K| 8831K| 12379 (1)| 00:02:29 |
| 16 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 17 | SORT AGGREGATE | | 1 | 66 | | |
|* 18 | TABLE ACCESS FULL | A | 85818 | 5531K| 12379 (1)| 00:02:29 |
| 19 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 20 | SORT AGGREGATE | | 1 | 66 | | |
|* 21 | TABLE ACCESS FULL | A | 111K| 7158K| 12379 (1)| 00:02:29 |
| 22 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 23 | SORT AGGREGATE | | 1 | 66 | | |
|* 24 | TABLE ACCESS FULL | A | 86539 | 5577K| 12379 (1)| 00:02:29 |
| 25 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 26 | SORT AGGREGATE | | 1 | 66 | | |
|* 27 | TABLE ACCESS FULL | A | 91587 | 5903K| 12379 (1)| 00:02:29 |
| 28 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 29 | SORT AGGREGATE | | 1 | 66 | | |
|* 30 | TABLE ACCESS FULL | A | 228K| 14M| 12379 (1)| 00:02:29 |
| 31 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 32 | SORT AGGREGATE | | 1 | 66 | | |
|* 33 | TABLE ACCESS FULL | A | 87981 | 5670K| 12379 (1)| 00:02:29 |
| 34 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 35 | SORT AGGREGATE | | 1 | 66 | | |
|* 36 | TABLE ACCESS FULL | A | 84376 | 5438K| 12379 (1)| 00:02:29 |
| 37 | VIEW | | 1 | 13 | 12379 (1)| 00:02:29 |
| 38 | SORT AGGREGATE | | 1 | 66 | | |
|* 39 | TABLE ACCESS FULL | A | 112K| 7251K| 12379 (1)| 00:02:29 |
------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 12 - filter("OBJECT_NAME" LIKE 'J%' OR "OBJECT_NAME" LIKE 'V%')
15 - filter("OBJECT_NAME" LIKE 'I%' OR "OBJECT_NAME" LIKE 'V%')
18 - filter("OBJECT_NAME" LIKE 'H%' OR "OBJECT_NAME" LIKE 'V%')
21 - filter("OBJECT_NAME" LIKE 'G%' OR "OBJECT_NAME" LIKE 'V%')
24 - filter("OBJECT_NAME" LIKE 'F%' OR "OBJECT_NAME" LIKE 'V%')
27 - filter("OBJECT_NAME" LIKE 'E%' OR "OBJECT_NAME" LIKE 'V%')
30 - filter("OBJECT_NAME" LIKE 'D%' OR "OBJECT_NAME" LIKE 'V%')
33 - filter("OBJECT_NAME" LIKE 'C%' OR "OBJECT_NAME" LIKE 'V%')
36 - filter("OBJECT_NAME" LIKE 'B%' OR "OBJECT_NAME" LIKE 'V%')
39 - filter("OBJECT_NAME" LIKE 'A%' OR "OBJECT_NAME" LIKE 'V%') --后者运行计划:
SQL> explain plan for
2 select
3 sum(case when object_name like 'A%' or object_name like 'V%' then 1 else 0 end) N0,
4 sum(case when object_name like 'B%' or object_name like 'V%' then 1 else 0 end) N1,
5 sum(case when object_name like 'C%' or object_name like 'V%' then 1 else 0 end) N2,
6 sum(case when object_name like 'D%' or object_name like 'V%' then 1 else 0 end) N3,
7 sum(case when object_name like 'E%' or object_name like 'V%' then 1 else 0 end) N4,
8 sum(case when object_name like 'F%' or object_name like 'V%' then 1 else 0 end) N5,
9 sum(case when object_name like 'G%' or object_name like 'V%' then 1 else 0 end) N6,
10 sum(case when object_name like 'H%' or object_name like 'V%' then 1 else 0 end) N7,
11 sum(case when object_name like 'I%' or object_name like 'V%' then 1 else 0 end) N8,
12 sum(case when object_name like 'J%' or object_name like 'V%' then 1 else 0 end) N9
13 from a; Explained. Elapsed: 00:00:00.01
SQL> @getplan
'general,outline,starts' Enter value for plan type: PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------
Plan hash value: 3918351354 ---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 66 | 12349 (1)| 00:02:29 |
| 1 | SORT AGGREGATE | | 1 | 66 | | |
| 2 | TABLE ACCESS FULL| A | 3097K| 194M| 12349 (1)| 00:02:29 |
--------------------------------------------------------------------------- Note
-----
- dynamic sampling used for this statement (level=2) 能够看出,前者10次全表扫描,后者1次全表扫描。 从而时间上也大大减少了。由58s减少到19s。
优化这个sql主要还是思路的转换。难点在于如何把10次全表扫描转化成1次全表扫描。 在OLAP中,能够加并行使sql速度更快。

相似group by的分组计数功能的更多相关文章

  1. SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表

    SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表 SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表 2013-10-09 23:09 by BI Wor ...

  2. oracle 如何通过分组计数查出重复数据?

      1.情景展示 现在,机构表数据中机构名称有重复数据,如何筛选出来? 2.分析 第一步:统计是否存在重复数据. 方式一: 方式二: 说明表中确实存在重复数据 第二步:统计重复次数及机构名称. 需要通 ...

  3. oracle 使用count()函数进行分组计数时所踩的坑!

      1.情景展示 需要对id_card字段按字符长度进行分组统计并进行计数. 2.错误方式 第一步:统计出id_card字段共存在几种情况. 第一种方式:distinct 第二种方式:group by ...

  4. 【转载】Sqlserver使用Group By进行分组并计算每个组的数量

    在SQL语句查询中,Group By语句时常用来进行分组操作,有时候在分组的同时还需要计算出每个组的数量多少.在Sqlserver数据库中可以使用Group By加Count聚合函数来实现此功能,即通 ...

  5. 脉冲计数功能在ESM335x-Linux主板上的实现

    1.综述 在工业控制中,经常需要获取脉冲信号计数值.频率.周期.占空比等参数.英创嵌入式主板ESM335X系列 Linux系统现已实现外部输入脉冲信号的计数.频率.周期.占空比测量功能. 主要功能及技 ...

  6. MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能

    MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能 由于MYSQL没有提供类似ORACLE中OVER()这样丰富的分析函数. 所以在MYSQ ...

  7. group by具有去重的功能

    group by具有去重的功能

  8. TF:Tensorflow定义变量+常量,实现输出计数功能—Jason niu

    #TF:Tensorflow定义变量+常量,实现输出计数功能 import tensorflow as tf state = tf.Variable(0, name='Parameter_name_c ...

  9. MYSQL-实现分组排序 对比 ORACLE 和SQLserver用 row_number() over(partition by ) 分组排序功能

    以下是个人笔记: 本文是为了理解 row_number() over(partition by )  和实现各种数据库的分组排序功能 select ROW_NUMBER()over( partitio ...

随机推荐

  1. 【Henu ACM Round#19 D】 Points on Line

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 考虑l..r这个区间. 且r是满足a[r]-a[l]<=d的最大的r 如果是第一个找到的区间,则直接累加C(r-l+1,3); ...

  2. MapReduce JOB 的输出与输出笔记。

    提高 MapReduce 价值,自定义输入和输出. 比如跳过存储到 HDFS 中这个耗时的布置. 而只是从原始数据源接受数据,或者直接将数据发送给某些处理程序. 这些处理程序在 MapReduce 作 ...

  3. ArcGIS api for javascript——地图配置-滑动器的刻度线、方向、大小的改变

    描述 本例展示了如果删除缩放等级滑动器的刻度线.通过设置esriConfig里的sliderLabel为null来实现: esriConfig.defaults.map.sliderLabel = n ...

  4. ArcGIS api for javascript——地图配置-定制平移动画

    描述 本例展示了当用户点击平移按钮时如何定制地图的动画.panDuration和panRate是Dojo动画属性,可以分别确定动画的duration和帧刷新的rate.这些属性的单位都是毫秒,panD ...

  5. ArcGIS api for javascript——显示多个ArcGIS Online服务

    描述 本例展示了如何使用按钮在地图里的两个不同的图层间切换.所有地图里的图层恰巧是来自ArcGIS Online的ArcGISTiledMapServiceLayers.按钮是Dojo dijit按钮 ...

  6. PostgreSQL数据库创建/删除

    方法1 - 系统命令 sudo su - postgres #切换到postgres用户(系统用户) createdb weichen #创建数据库 psql #直接訪问数据库(默认进入本地postg ...

  7. Android开发之Volley网络通信框架

    今天用了一下Volley网络通信框架,感觉挺好用的,写个博客记录一下用法.方便以后VC. Volley(Google提供的网络通信库,能使网络通信更快,更简单,更健壮.) 功能模块: 1. JSON, ...

  8. PHP长整型在32位系统中强制转化溢出

    CleverCode近期遇到一个PHP项目整形转化问题,mysql有一个字段id是bigint的,里面有长整型,如id = 5147486396.可是php代码因为历史原因却部署在多台机器中,当中A机 ...

  9. vue2.0-transition配合animate.css

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. HDU 1512 左偏树+并查集

    思路: 左偏树里面掺了一些并查集的应用 这里放一份左偏树的代码模板 重点就是merge函数了-- int merge(int k1,int k2){ if(!k1||!k2)return k1+k2; ...