`
mikixiyou
  • 浏览: 1101722 次
  • 性别: Icon_minigender_1
  • 来自: 南京
博客专栏
C3c8d188-c0ab-3396-821d-b68331e21226
Oracle管理和开发
浏览量:354014
社区版块
存档分类
最新评论

一个分组统计SQL的优化过程(4)

阅读更多

接: http://mikixiyou.iteye.com/blog/1491153

一个分组统计SQL的优化过程(1)

接: http://mikixiyou.iteye.com/blog/1491177

一个分组统计SQL的优化过程(2)

接: http://mikixiyou.iteye.com/blog/1491283

一个分组统计SQL的优化过程(3)


优化

这个 SQL 优化像交通堵塞疏导一样。我们可以将车站比做磁盘文件,道路比作内存,车子比做数据块,乘客比做数据记录。所有乘客按照进站顺序坐在不同的车子的各个座位上。

假如,一个车站,里面有 5 辆车子,一共进来 100 个乘客。这些乘客会根据车站管理员的要求,按照进站顺序依次坐在车站里 10 辆车子上。我们将这些车子按照 A B C D E 编号,将乘客按照进站顺序按照 1..100 编号。这些乘客去哪里不是上车就座时决定的,而是大家都坐好后由车站管理员的老板决定的。老板决定籍贯为上海的乘客去某地,车站管理员找出籍贯为上海的 1 21 42 63 84 号乘客去某地,于是我们得找到这些乘客目前在哪些车辆上。很不幸,这 5 个乘客在 A B C D E 5 辆车上,车站管理员不能让这些乘客都下来坐另一辆车,也不能空一辆出来,于是只好 5 辆车同时出门了。上路一看,就两道,得排队在道路上跑。

大家会不会觉得这车站管理员是多么得愚蠢?

车站管理员竟然按照进来乘客进站的顺序将他们依次坐在依次排开的车子上,而不是按乘客的籍贯尽可能地将籍贯相同的乘客安排在同一车子上。问题是管理员事先是不知道老板怎么会以籍贯来决定呢,乘客自己也不知道,决定乘客是否到哪里是老板决定的。从车站管理员的角度看,将乘客按进站顺序放到车子上,是最合理的,这样最快地将乘客安排上车。

老板是怎么决定的呢?如根据籍贯,决定籍贯为上海的都拉出来;如根据收入,决定收入超过 5000 每月的都拉出来。

针对当前的问题,做为车站管理员能想到什么方法呢?

一种方法是将路拓宽,保证这么所有的车辆一起通行;另一种方法是将籍贯相同的乘客在上车时就放在同一辆车子,这样只要一辆车就能将这些乘客拉出去。

回到数据库系统层面,我们先看第二种方法。

这个 SQL 是按照 brhid 进行分组查询,就是说,将 brhid 相同的记录先去出来。如果我们将表中 brhid 相同的记录都尽量保存一个数据块中而不是像现在这样随机地散落在任意的数据块中。记录重新分布后,则搜索一个 brhid 的记录时,就会尽可能少地读取数据块。

我们继续以 brhid=’8088’ 举例,每个数据块能最多存储 17 条记录,一共约 9600 条记录。算一下,我们需要的数据块数也就 500 600 个,加上 10% 的空闲空间,最大不会超过 700 个数据块。和现在的 10688 个数据块,相差 12 倍之多。

按照 brhid 排序建立一张临时表,将 brhid 相同的记录尽可能地保存在一起。方法如下 :

Create table cust_info_bk2 nologging as select * from cust_info order by brhid;

在新表中,记录是按照 brhid 排序进入表的,因此相同 brhid 的记录都会保存在一起,空间占用的 block 都是相邻的。

SQL> select count(*)
  2    from (select distinct dbms_rowid.rowid_relative_fno(rowid) f,
  3                          dbms_rowid.rowid_block_number(rowid) b
  4            from  cust_info­_bk2
  5           where brhid = '8088');

  COUNT(*)
----------
       684

这些记录只 保存在 684 个数据块中。

这个优化操作能保证我们优化的 SQL 能从遍历 1W 个数据块降低到 684 个数据块。数据块的减少,也能使得磁盘读降低。没有了这些磁盘读, SQL 执行的性能也将大幅提升。

测试结果也证实,每次查询都在秒级,而原表的查询时间则是几十秒,可见这个优化措施效果明显。这个效果也是可以理解的,读取的数据块小了,性能自然会有提升。而且,读取的数据块完全在内存里,不需要再次去读取磁盘,这才是性能提升的决定性的因素。

这种方法确实是有效果的。但如果同一 brhid 需要的数据块非常多,多到一定程度上,问题就会回到原点。

我们已经很清楚,是内存读很大,导致了磁盘读。又是磁盘度导致了运行时间上升,性能下降。这个表也只有 25W 数据块合计 2GB 的空间,我们完全可以将他全部地放入内存中,使之常驻缓存。这样就不会因为 LRU 机制而被自动清理出缓存,从而导致再次读取时的磁盘读。

若我们将 2GB 的表放入内存中,则读取该表时所涉及的数据块都会在计算机内存中,既使不在所请求实例的内存中,也就是多一次或两次的网络传输,数据块从 holding 到复制到所请求的实例中,再读取出来。这样也比从磁盘读取强 1-2 个数量级。

RAC 环境下,进程读取一个数据块比单实例复杂。单实例环境下,进程读取数据块,若在内存中,则直接读取到;若不在内存中,则会去磁盘文件读取数据到内存中,再取到数据块。多节点的 RAC 环境下,进程读取数据块,首先从 GCS 去判断数据块在哪个实例的内存中。若刚好在所请求实例的内存中,则读取到;若不在请求实例的内存,则会通过 GCS 返回的信息去找这个数据块在哪个实例中,找到这个实例,通过心跳网络复制数据块到请求实例;若都不在,则直接去读磁盘文件。

如何将数据库对象缓存进内存而不会因为 LRU 机制而清理出去呢。 Oracle 提供另一种缓存空间,称之为 keep pool 。这个空间管理机制采用的是队列机制,所缓存的对象先进先出。 keep pool defult pool 都是 block buffer ,两个池的大小由参数 db_keep_cache_size db_cache_size 决定。

操作方法如下:

SQL> ALTER TABLE CUST_INFO STORAGE(buffer_pool keep);

SQL> ALTER TABLE CUST_INFO CACHE;

注:这个操作需要先在数据库初始化参数里配置 db_keep_cache_size 项后才能生效。

分享到:
评论

相关推荐

    sql脚本优化

    下面是sql语句优化的一些提示要点,主要讲述的是操作符优化过程。 IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。 但是用IN的SQL性能总是比较低的,从sql执行的步骤来...

    MySQL数据库优化SQL篇PPT课件.pptx

    本PPT课件主要讲述了MySQL数据库优化的重要知识点,特别是SQL优化方面的内容。从执行计划、SELECT语句、IN和EXIST语句、LIMIT语句、RAND函数、Order by、Group by、Distinct和Count等方面对MySQL数据库优化进行了...

    SQL优化指导示例2.pdf

    在这部分中,还可以看到有“NOSTATISTICS”标记,表明系统可能没有足够的统计信息来准确预估查询的成本和行数,这在优化过程中是需要关注的。 在优化SQL查询时,一个重要的方面是理解并合理使用聚合函数和分组...

    数据库面试题索引sql优化

    通过`TO_CHAR`函数将日期转换为字符串形式,然后按照年份进行分组统计平均工资。 **题目8.9:** 查询EMP员工表下每个部门工资前二名的员工信息。 **解答:** ```sql SELECT DEPTNO, ENAME, SAL FROM EMP E1 WHERE ...

    oracle sql优化

    总结来说,Oracle SQL优化是一个综合性的任务,需要考虑索引、连接方式、查询结构等多个方面。理解并应用上述知识点,能够帮助你更好地管理和优化你的Oracle数据库,实现更高效的SQL执行。通过持续学习和实践,你...

    SQL优化教程

    ### SQL优化教程 #### 一、SQL优化的重要性与原则 ...综上所述,SQL优化是一个综合性的过程,涉及从SQL语句本身到数据库架构设计的方方面面。通过对上述方法的合理应用,可以显著提高系统的查询性能和响应速度。

    Oracle Sql 优化

    总结,Oracle SQL优化是一个综合性的过程,涉及到SQL语句的编写、数据库结构的设计、索引的管理和优化器的配置等多个方面。通过对上述策略的理解和应用,可以显著提高Oracle数据库的性能和响应速度,为用户提供更好...

    基于Oracle的SQL优化典型案例分

    然而,随着数据量的增长,SQL查询的性能优化成为了一个关键问题。本篇将深入探讨“基于Oracle的SQL优化典型案例分析”,旨在帮助数据库管理员和开发人员提升SQL查询效率,降低系统负载,从而提高整体系统性能。 1. ...

    自动执行SQL语句&创建标准的Sql 存储过程

    例如,每当有新的订单插入,可以触发一个存储过程来计算并更新销售统计信息。 在实践中,这些功能极大地提高了数据库管理的效率和灵活性。然而,需要注意的是,过度依赖存储过程可能会增加维护难度,因为它们可能与...

    MySQL 最佳SQL优化实践手册

    B-tree索引由于其平衡树的特性,适合用于范围查询、排序和分组统计等操作,能够大幅提升查询效率。而hash索引由于其快速的查找性能,在内存表中使用时可以发挥巨大优势,但由于其散列后数据随机存储的特性,不便于...

    通过分析SQL语句的执行计划优化SQL语句

    4. **排序与分组操作**:执行计划中会显示是否需要进行排序或分组操作,以及这些操作是如何完成的。不必要的排序和分组会消耗大量资源。通过调整查询语句,避免无用的排序和分组,可以提升性能。 5. **统计信息更新...

    通过分析SQL语句的执行计划优化SQL

    每个操作都有一个成本值,表示完成该操作所需的资源量。数据库会选取总成本最低的执行计划。 二、查看SQL执行计划 在Oracle中,可以使用`EXPLAIN PLAN`或`DBMS_XPLAN`包来查看执行计划。例如,使用`EXPLAIN PLAN ...

    sql试题及答案,sql 行列转换,sql存储过程实例

    通过学习这些SQL试题、行列转换技巧和存储过程实例,你可以全面提升SQL技能,无论是日常的数据查询还是复杂的业务逻辑处理,都能得心应手。在实际工作中,不断练习和探索,将理论知识转化为实践能力,是成为SQL高手...

    sql server 性能优化(生产中常用)

    查看SQL语句的执行计划是优化过程中的一个重要步骤。执行计划可以详细显示SQL语句如何被数据库解析、编译和执行。通过分析执行计划,可以了解是否有不必要的表扫描或索引扫描发生,以及是否有潜在的性能问题,例如...

    Oracle SQL优化实例讲解.pdf

    通过上述知识点的详细说明,我们可以了解到Oracle SQL优化涉及多个层面的内容,从具体的优化技巧到理论概念,从基本的操作到高级的性能分析工具,每一个环节都是优化过程中不可或缺的一环。通过实例讲解,能够更加...

    SQL常用优化脚本,优化SQL语句

    - **设置单用户模式**:`EXEC sp_dboption 'db_Name', 'singleuser', 'TRUE'`将数据库设置为只允许一个用户访问,通常在进行数据库检查或维护时使用。 - **检查并修复数据库**: - `dbcc checkdb('db_Name', repair...

    sql server2005/2008 性能优化大全 .pptx

    **3.2 SQL数据排序、分组和统计技巧** 正确使用`ORDER BY`、`GROUP BY`和`SUM`、`COUNT`等聚合函数可以有效提高查询效率。例如,合理地使用`GROUP BY`可以减少不必要的行。 **3.3 SQL Server查询速度慢的原因** -...

    PLSQL基础,sql优化

    第六章“分组统计”介绍了GROUP BY和聚合函数(如COUNT, SUM, AVG, MAX, MIN)的用法,它们用于对数据进行汇总分析。在优化过程中,正确使用GROUP BY和HAVING子句可以显著提升查询性能。 第七章“子查询”阐述了...

    SQL性能优化

    由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。  NOT IN  此操作是强列推荐不使用的,因为不能应用表的索引。  推荐方案:用NOT EXISTS 或...

    HibernateTemplate分组统计

    2. **分组统计**:指通过SQL语句对查询结果按照一个或多个字段的值进行分组,并对每个分组进行计数或其他聚合操作的过程。 3. **Spring框架**:一个开源的应用程序框架,旨在简化企业级应用程序的开发过程。Spring...

Global site tag (gtag.js) - Google Analytics