子查询

--使用子查询提升count distinct的效率
数据库:38_6543 db_hyrhk

--1.count distinct很有用,但太慢
----Count distinct是SQL分析时的祸根所以拿它来做个例子
----首先,让我们以我们一直使用的一个简单查询开始:查看案件涉及当事人大于200的案件
select 
  t_aj_all.c_ajbh, 
  count(distinct t_dsr_allbak.c_bh)
from t_aj_all
 join t_dsr_allbak on t_dsr_allbak.c_ajbh = t_aj_all.c_ajbh
group by t_aj_all.c_ajbh having count(distinct t_dsr_allbak.c_bh)>200
order by count desc
耗时:8.573s
----它慢是因为数据库遍历了所有当事人以及所有的案件,然后join它们,再将它们排序,这些都在真正的group和分组和聚合工作之前。

--2.先聚合,然后Join
----group-聚合后的任何工作代价都要低,因为数据量会更小。:

select
  t_aj_all.c_ajbh,
  dsr.ct
from t_aj_all
join (
  select 
    c_ajbh,
    count(distinct c_bh) as ct
  from t_dsr_allbak 
  group by c_ajbh having count(distinct c_bh)>200
) dsr 
on dsr.c_ajbh = t_aj_all.c_ajbh
order by dsr.ct desc
耗时:7.822s
----正如设计的,group-聚合在join之前。

--3.先将数据集缩小
----我们可以做的更好。通过在整个当事人表上group-聚合,我们处理了数据库中很多不必要的数据。
----我们可以预先计算差异,而不是处理全部数据,这样只需要一个哈希集合。然后我们在此基础上做一个简单的聚集即可。

select
  t_aj_all.c_ajbh,
  counts.ct
from t_aj_all 
inner join (
  select distinct_dsr.c_ajbh, 
  count(1) as ct
  from (
    select distinct c_ajbh, c_bh
    from t_dsr_allbak
  ) as distinct_dsr
  group by distinct_dsr.c_ajbh having  count(1) >200
) as counts 
on counts.c_ajbh = t_aj_all.c_ajbh
order by counts.ct desc
耗时:1.948s
----我们采取内部的count-distinct-group,然后将数据拆成两部分分成两块。第一块计算distinct (c_ajbh, c_bh) 。第二块在它们基础上运行一个简单group-count。跟上面一样,最后再join。
----通常,数据大小和类型很重要。上面的例子受益于基数中没多少换算。distinct (c_ajbh, c_bh)相对于数据总量来说数量也很少。不同的对数越多,用来group和计数的唯一数据就越多——代价便会越来越大。

--总结:下一遇到长时间运行的count distinct时,尝试一些子查询吧。

什么是临时表(with as)

with as 语法:WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会 被整个SQL语句所用到。如果WITH AS短语所定义的表名被调用两次以上,则优化器会自动将 WITH AS短语所获取的数据放入一个TEMP表里,如果只是被调用一次,则不会。而提示materialize则是强制将WITH AS 短语里的数据放入一个全局临时表里。很多查询通过这种方法都可以提高速度

是公用表表达式,可以理解为创建临时表。比如
WITH A AS(SELECT * FROM TABLE1)
SELECT * FROM A

with as语法
–针对一个别名
with tmp as (select * from tb_name)

–针对多个别名
with
   tmp as (select * from tb_name),
   tmp2 as (select * from tb_name2),
   tmp3 as (select * from tb_name3)

  1. --相当于建了个e临时表
  2. with e as (select * from scott.emp e where e.empno=7499)
  3. select * from e;
  4. --相当于建了e、d临时表
  5. with
  6. e as (select * from scott.emp),
  7. d as (select * from scott.dept)
  8. select * from e, d where e.deptno = d.deptno;

其实就是把一大堆重复用到的sql语句放在with as里面,取一个别名,后面的查询就可以用它,这样对于大批量的sql语句起到一个优化的作用,而且清楚明了

--样例:
--1.
select
  t_aj_all.c_ajbh,
  log_counts.ct
from t_aj_all 
inner join (
  select distinct_logs.c_ajbh, 
  count(1) as ct
  from (
    select distinct c_ajbh, c_bh
    from t_dsr_allbak
  ) as distinct_logs
  group by distinct_logs.c_ajbh having  count(1) >200
) as log_counts 
on log_counts.c_ajbh = t_aj_all.c_ajbh
order by log_counts.ct desc

with distinct_logs as 
(  select distinct c_ajbh, c_bh
   from t_dsr_allbak
), 
log_counts as 
(
  select distinct_logs.c_ajbh, 
  count(1) as ct
  from distinct_logs group by distinct_logs.c_ajbh having  count(1) >200
)
select
t_aj_all.c_ajbh,
  log_counts.ct
from t_aj_all 
inner join log_counts
on log_counts.c_ajbh = t_aj_all.c_ajbh
order by log_counts.ct desc

--2.
select
  t_aj_all.c_ajbh,
  dsr.ct
from t_aj_all
join (
  select 
    c_ajbh,
    count(distinct c_bh) as ct
  from t_dsr_allbak 
  group by c_ajbh having count(distinct c_bh)>200
) dsr 
on dsr.c_ajbh = t_aj_all.c_ajbh
order by dsr.ct desc

with dsr as (  select 
    c_ajbh,
    count(distinct c_bh) as ct
  from t_dsr_allbak 
  group by c_ajbh having count(distinct c_bh)>200)
  
  select   t_aj_all.c_ajbh,
  dsr.ct
from t_aj_all
join dsr on dsr.c_ajbh = t_aj_all.c_ajbh
order by dsr.ct desc

区别:

EXPLAIN ANALYZE
with solution as(
        SELECT
        c_id,
        c_task_mc,
        d_createtime,
        n_status,
        c_graph_version
        FROM
        db_solution.t_solution_task
        ),
        temp as(
        SELECT
        c_id,
        MAX (d_createtime) AS d_createtime
        FROM
        db_solution.t_solution_task_his
        GROUP BY
        c_id
        ),
        solutionhis as(
        SELECT
        A .c_id,
        A .c_task_mc,
        A .d_createtime,
        A .n_status,
        A .c_graph_version
        FROM
        db_solution.t_solution_task_his A
        left join temp on A.c_id = temp.c_id and A.d_createtime=temp.d_createtime
        left join solution on A.c_id= solution.c_id
        where temp.c_id is not null and solution.c_id is null)
        select
        COUNT (DISTINCT task.c_id)
        from
        db_solution.t_task task
        left join solution on task.c_id = solution.c_id
        left join solutionhis on task.c_id = solutionhis.c_id
        LEFT JOIN db_solution.t_task_process_graph gra ON task.c_id = gra.c_task_id AND
        task.c_graph_version = gra.c_version
        
        
        EXPLAIN ANALYZE
        select
        COUNT (DISTINCT task.c_id)
        from
        db_solution.t_task task
        left join db_solution.t_solution_task solution on task.c_id = solution.c_id
        left join (        SELECT
        A .c_id,
        A .c_task_mc,
        A .d_createtime,
        A .n_status,
        A .c_graph_version
        FROM
        db_solution.t_solution_task_his A
        left join (        SELECT c_id,MAX (d_createtime) AS d_createtime FROM db_solution.t_solution_task_his GROUP BY c_id)temp on A.c_id = temp.c_id and A.d_createtime=temp.d_createtime
        left join db_solution.t_solution_task solution on A.c_id= solution.c_id
        where temp.c_id is not null and solution.c_id is null) solutionhis on task.c_id = solutionhis.c_id
        LEFT JOIN db_solution.t_task_process_graph gra ON task.c_id = gra.c_task_id AND
        task.c_graph_version = gra.c_version

SQL --子查询与临时表相关推荐

  1. sql子查询示例_SQL更新查询示例说明

    sql子查询示例 In this article, we're going to learn how to use the SQL update statement - what it is, wha ...

  2. sql子查询示例_学习SQL:SQL查询示例

    sql子查询示例 In the previous article we've practiced SQL, and today, we'll continue with a few more SQL ...

  3. sql 子查询 嵌套查询_SQL子查询– SQL中的嵌套查询

    sql 子查询 嵌套查询 In the real world, there are times when we need a particular set of data but we don't h ...

  4. sql 子查询及基本语句 挺全的收录

    引自https://blog.csdn.net/jia_gugang/article/details/80282873 一.SQL子查询语句 1.单行子查询         select ename, ...

  5. SQL子查询、关联查询

    SQL子查询.关联查询: 注:以上内容仅提供参考和交流,请勿用于商业用途,如有侵权联系本人删除! 持续更新中- 如有对思路不清晰或有更好的解决思路,欢迎与本人交流,QQ群:273557553,个人微信 ...

  6. sql子查询的妙用:用在from后面做子表、用在where后面做子条件以及用在select后面用作子字段

    昨天去客户方让客户小姐姐给我查询一段sql的时候,竟然发现sql子查询还可以这样写: sql子查询不仅仅可以出现在from 后面作为表结构,譬如: select t1.company_id,t1.co ...

  7. 解决 SQL 子查询 group by去重 索引失效 的一种思路

    子查询和索引一直是性能优化的常客 查询简单的时候还好办,拿掉子查询,先join再group by聚合 碰到复杂的查询,里外查询维度不统一,还牵扯到别的计算指标,有点难搞 用临时表是可行的,写过程,创建 ...

  8. mysql 新建子查询_Mysql创建SQL子查询ALIAS

    通常这些被称为视图.例如: CREATE VIEW vMyLongQuery AS SELECT a, b, c FROM (LONG QUERY) X WHERE ... 然后可以像这样引用: SE ...

  9. mysql+sql+子查询语句_SQL子查询

    子查询或内部查询或嵌套查询在另一个SQL查询的查询和嵌入式WHERE子句中. 子查询用于返回将被用于在主查询作为条件的数据,以进一步限制要检索的数据. 子查询可以在SELECT,INSERT,UPDA ...

最新文章

  1. PHP安装扩展mcrypt以及相关依赖项 【PHP安装PECL扩展的方法】
  2. UIButton长按事件
  3. 实验四 数据库SQL语言基础编程
  4. android adb命令
  5. apple wwdc resource
  6. 这65条工作和成长建议,你将受用终生!
  7. javap的用途不断发展:您的Java类文件中隐藏了什么?
  8. HTML渐变背景不重复,如何停止重复自身的背景颜色渐变? (css)
  9. tensorflow 初认识
  10. [Python]小甲鱼Python视频第037课(类和对象:面向对象编程 )课后题及参考解答
  11. 我解决了net framework 4安装失败,提示找不到指定文件的问题
  12. 【解决方案】SkeyeARS及SkeyeIVMS技术助力地铁安防视频监控系统建设
  13. php 孤儿进程组,孤儿进程组(Orphaned Process Groups) APUE2学习笔记
  14. 2021年「博客之星」参赛博主:南浔Pyer
  15. 2021-01-12 DataGrip2020.3 离线安装驱动
  16. bcedit双系统更改启动项名称_Win7下双系统修改BCD启动项名称
  17. right 微信小程序_js实现微信小程序左右滑动功能
  18. Windows必备:五款靠谱好用的软件,简洁纯净无广告
  19. PNG文件编码解析之PNG文件格式中的所有数据块以及标识
  20. h1283命令行下刷机法

热门文章

  1. 微信账户体系科普:什么是UnionId、OpenId与wxopenid?
  2. 企业进行风险控制的重要意义
  3. 通过亚马逊云科技实现基于 Restful API 的 CloudFront Distribution 复制/克隆功能
  4. 《一封来自日本的信——2018年日本社会和生活水平现状》 摘要
  5. 迄今见过的最好的职业规划的文章
  6. android studio项目中将普通文件夹变成moudle
  7. 如何打开usb计算机连接网络设置,usb共享网络怎么用
  8. 小米miui开发版系统获取root权限的方法
  9. java media player 设置音量_SoundPlayer可调音量 - c#
  10. 安卓游戏内购破解之滚动的天空