SQL --子查询与临时表
子查询
--使用子查询提升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)
- --相当于建了个e临时表
- with e as (select * from scott.emp e where e.empno=7499)
- select * from e;
- --相当于建了e、d临时表
- with
- e as (select * from scott.emp),
- d as (select * from scott.dept)
- 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 --子查询与临时表相关推荐
- sql子查询示例_SQL更新查询示例说明
sql子查询示例 In this article, we're going to learn how to use the SQL update statement - what it is, wha ...
- sql子查询示例_学习SQL:SQL查询示例
sql子查询示例 In the previous article we've practiced SQL, and today, we'll continue with a few more SQL ...
- sql 子查询 嵌套查询_SQL子查询– SQL中的嵌套查询
sql 子查询 嵌套查询 In the real world, there are times when we need a particular set of data but we don't h ...
- sql 子查询及基本语句 挺全的收录
引自https://blog.csdn.net/jia_gugang/article/details/80282873 一.SQL子查询语句 1.单行子查询 select ename, ...
- SQL子查询、关联查询
SQL子查询.关联查询: 注:以上内容仅提供参考和交流,请勿用于商业用途,如有侵权联系本人删除! 持续更新中- 如有对思路不清晰或有更好的解决思路,欢迎与本人交流,QQ群:273557553,个人微信 ...
- sql子查询的妙用:用在from后面做子表、用在where后面做子条件以及用在select后面用作子字段
昨天去客户方让客户小姐姐给我查询一段sql的时候,竟然发现sql子查询还可以这样写: sql子查询不仅仅可以出现在from 后面作为表结构,譬如: select t1.company_id,t1.co ...
- 解决 SQL 子查询 group by去重 索引失效 的一种思路
子查询和索引一直是性能优化的常客 查询简单的时候还好办,拿掉子查询,先join再group by聚合 碰到复杂的查询,里外查询维度不统一,还牵扯到别的计算指标,有点难搞 用临时表是可行的,写过程,创建 ...
- mysql 新建子查询_Mysql创建SQL子查询ALIAS
通常这些被称为视图.例如: CREATE VIEW vMyLongQuery AS SELECT a, b, c FROM (LONG QUERY) X WHERE ... 然后可以像这样引用: SE ...
- mysql+sql+子查询语句_SQL子查询
子查询或内部查询或嵌套查询在另一个SQL查询的查询和嵌入式WHERE子句中. 子查询用于返回将被用于在主查询作为条件的数据,以进一步限制要检索的数据. 子查询可以在SELECT,INSERT,UPDA ...
最新文章
- PHP安装扩展mcrypt以及相关依赖项 【PHP安装PECL扩展的方法】
- UIButton长按事件
- 实验四 数据库SQL语言基础编程
- android adb命令
- apple wwdc resource
- 这65条工作和成长建议,你将受用终生!
- javap的用途不断发展:您的Java类文件中隐藏了什么?
- HTML渐变背景不重复,如何停止重复自身的背景颜色渐变? (css)
- tensorflow 初认识
- [Python]小甲鱼Python视频第037课(类和对象:面向对象编程 )课后题及参考解答
- 我解决了net framework 4安装失败,提示找不到指定文件的问题
- 【解决方案】SkeyeARS及SkeyeIVMS技术助力地铁安防视频监控系统建设
- php 孤儿进程组,孤儿进程组(Orphaned Process Groups) APUE2学习笔记
- 2021年「博客之星」参赛博主:南浔Pyer
- 2021-01-12 DataGrip2020.3 离线安装驱动
- bcedit双系统更改启动项名称_Win7下双系统修改BCD启动项名称
- right 微信小程序_js实现微信小程序左右滑动功能
- Windows必备:五款靠谱好用的软件,简洁纯净无广告
- PNG文件编码解析之PNG文件格式中的所有数据块以及标识
- h1283命令行下刷机法
热门文章
- 微信账户体系科普:什么是UnionId、OpenId与wxopenid?
- 企业进行风险控制的重要意义
- 通过亚马逊云科技实现基于 Restful API 的 CloudFront Distribution 复制/克隆功能
- 《一封来自日本的信——2018年日本社会和生活水平现状》 摘要
- 迄今见过的最好的职业规划的文章
- android studio项目中将普通文件夹变成moudle
- 如何打开usb计算机连接网络设置,usb共享网络怎么用
- 小米miui开发版系统获取root权限的方法
- java media player 设置音量_SoundPlayer可调音量 - c#
- 安卓游戏内购破解之滚动的天空