oracle 使从表中随机取出一行记录数据

news2024/9/28 19:23:08

select * from (select rownum no, a.* from   a 
  where  status_code ='AVAILABLE' and  id_type = 'MEM' and archive_flag = 'N' and rownum<=1000000 ) where no >=1000000-1 for update

随机取一条,锁住记录,操作完archive_flag = 'Y'不会再取。

  1. 四种解决方案:

  2. 测试数据90万条

  3. 方案一:使用dbms_random.random 对数据排序,然后取出第一条,不过这种效率太低,用时3-4秒。

  4. SELECT *FROM (SELECT * FROM TEMP_CODES ORDER BY dbms_random.random) where rownum =1

  5. 方案二:使用dbms_random.value 对数据排序,与方案一如出一辙

  6. select * from (select * from TEMP_CODES order by dbms_random.value) where rownum<=1

  7. 或者使用row_number 函数

  8. SELECT CODE

  9. FROM ( SELECT CODE, ROW_NUMBER() OVER (ORDER BY dbms_random.value) rn FROM TEMP_CODES )

  10. WHERE rn = 1;

  11. 方案三:使用sample随机取样,取得一条随机行,由于是随机样,所以在数据量逐渐变少的时候,取样会出现无法取到的情况,可以通过多次取样来满足始终能取到数据。

  12. 选择0.001%的记录

  13. select *from TEMP_CODES sample(0.001) WHERE FLAG=0 AND ROWNUM=1;

  14. 选择20%的记录

  15. select *from TEMP_CODES sample(20) WHERE FLAG=0 AND ROWNUM=1;

  16. 选择50%的记录

  17. select *from TEMP_CODES sample(50) WHERE FLAG=0 AND ROWNUM=1;

  18. 选择70%的记录

  19. select *from TEMP_CODES sample(70) WHERE FLAG=0 AND ROWNUM=1;

  20. 选择99.99%的记录

  21. select *from TEMP_CODES sample(99.9999) WHERE FLAG=0 AND ROWNUM=1;

  22. 方案四:查询包含条件的记录总数,通过这个记录总数随机生成一个小于等于这个记录总数的数,通过这个随机数去取得记录行。

  23. 1、查询剩余的总数记录数:当前为90万

  24. 2、生成1-90万之间的随机数randomNum

  25. 3、通过随机数查询。

  26. select * from (select rownum no,code from TEMP_CODES where rownum<=randomNum ) where no >=randomNum

  27. 以上四种方案皆可得到随机一行记录。个人还是比较倾向于方案三。

  1. 1.根据ROWID来分

  2. select * from t_xiaoxi where rowid in(select rid from (select rownum rn,rid from(select rowid rid,cid from

  3. t_xiaoxi order by cid desc) where rownum<10000) where rn>9980) order by cid desc;

  4. 2.按分析函数来分

  5. select * from (select t.*,row_number() over(order by cid desc) rk from t_xiaoxi t) where rk<10000 and rk>9980;

  6. 3.按ROWNUM来分

  7. select * from(select t.*,rownum rn from(select * from t_xiaoxi order by cid desc) t where rownum<10000) where

  8. rn>9980

记录一次Oracle数据库千万级数据表的分页性能优化

项目背景:

        公司有一个项目用的是oracle数据库,用户数据量比较大。有1200w+(其实也不多)。然后在分页查询的时候到300w左右的时候就比较慢了,大概要3s+,到600w左右的时候要6s+。其实这个表的查询并不复杂。就是一个单表的数据分页查询。

原来的分页SQL-1:

        通过使用逻辑分页行编号值ROWNUM进行分页

SELECT * FROM
    (SELECT
        T.*, ROWNUM AS ROWNO FROM
        (SELECT
            CUST_ID,
            CUST_NAME,
            CUST_NAT,
            CERT_NO,
            ORG_ID,
            TO_CHAR(CREATE_DT, 'YYYY-MM-DD') AS CREATE_DT,
            GENDER
        FROM xx_xx
        WHERE 1 = 1) T) R
WHERE ROWNO >= 3000000 AND ROWNO <= 3000050;

修改过的分页SQL-2:

        也是通过逻辑分页编号值ROWNUM进行分页

SELECT * FROM
    (SELECT
        T.*,
        ROWNUM AS ROWNO
    FROM
        (SELECT
            CUST_ID,
            CUST_NAME,
            CUST_NAT,
            CERT_NO,
            ORG_ID,
            TO_CHAR(CREATE_DT, 'YYYY-MM-DD') AS CREATE_DT,
            GENDER
        FROM xx_xxWHERE
            1 = 1 AND ROWNUM <= 3000050) T) R
WHERE ROWNO>3000000;

  

修改过的分页SQL-3:

        使用物理分页行编号值rowid

SELECT
    CUST_ID,
    CUST_NAME,
    CUST_NAT,
    CERT_NO,
    ORG_ID,
    TO_CHAR(CREATE_DT, 'YYYY-MM-DD') AS CREATE_DT,
    GENDER
FROM
    T2A_CUST_I
WHERE rowid IN (
    SELECT t2.rid
    FROM
        (SELECT
            t1.*,
            ROWNUM rn
        FROM
            (SELECT
                CUST_ID,
                CUST_NAME,
                CUST_NAT,
                CERT_NO,
                ORG_ID,
                TO_CHAR(CREATE_DT, 'YYYY-MM-DD') AS CREATE_DT,
                GENDER,
                rowid AS rid
            FROM xx_xx
            WHERE 1 = 1) t1)t2
    WHERE rn>3000000 AND rn < 3000050);

 分析:

      1、ROWNUM和rowid的区别? ROWNUM是逻辑地址,表示查询耨条记录在整个结果集中的位置,同一条记录查询条件不同对应的rownum是不同的二rowid是不会变的。rowid是物理地址,用于定位数据表中某条数据的位置,是唯一的、不会改变的,查询快

      2、SQL-1和SQL-2都是通过ROWNUM来分页的,效果为什么会有很大差距?这个网上很多都是说CBO优化模式,Oracle可以讲外层的查询条件推到内层查询中,以提高内层查询的执行效率。很多帖子都在。大家自己可以了解一下。

        

性能对比
3000000-30000506000000-60000509000000-9000050
SQL-17.8s8s8.2
SQL-22.2s4.4s6.5s
SQL-32.9s2.8s

2.7

对于Oracle中分页排序查询语句执行效率的比较分析
作者:lzgame
在工作中我们经常遇到需要在Oracle中进行分页、排序、查询的组合SQL语句,举例来说,通常我们会这样写:(假定表test中id是主键,并且id从1开始没有间断顺序排列)

1. SELECT * FROM (
      SELECT id,a1,a2,a3,a4,a5,a6,a7,a8,a9, ROWNUM AS rn FROM test
      WHERE a1 LIKE '%%' AND ROWNUM<=1000000
      ORDER BY id
    ) t2 WHERE  rn>=999990;

但是由于ROWNUM是一个伪列,Oracle会首先查询满足ROWNUM<=1000000条件的记录,然后再对得到的记录进行排序,这就导致我们并不能获得期望的排序结果。本应得到id为999990-1000000,实际上却得到了一些无规律并令人困惑的id结果。于是我做了以下改进;

2. SELECT * FROM (
      SELECT id,a1,a2,a3,a4,a5,a6,a7,a8,a9, ROWNUM AS rn FROM (
        SELECT id,a1,a2,a3,a4,a5,a6,a7,a8,a9 FROM test
        WHERE a1 LIKE '%%'
        ORDER BY id
      ) t1 WHERE  ROWNUM<=1000000
    ) t2 WHERE  rn>=999990;

显然,通过经典的三层分页排序查询结构,我确实得到了想要的结果。但是在数据量很大的数据表中,由于需要首先取得排序后的全部数据集,导致了执行效率的极速降低,直至无法忍受。为了提高性能,我在网上查阅了很多资料,其中有一种说法是:当排序条件使用的关键字是主键或索引,并在WHERE子句中先于ROWNUM使用过该关键字时,我们就可以采用1号语句获得想要的结果了,于是我改写了1号语句并进行了测试:

3. SELECT * FROM (
      SELECT id,a1,a2,a3,a4,a5,a6,a7,a8,a9, ROWNUM AS rn FROM test
      WHERE id>=0 AND ROWNUM<=1000000
      ORDER BY id
    ) t2 WHERE  rn>=999990;

我惊喜的发现确实有效,我成功了,但惊喜并没有持续多久,因为当我把查询条件“a1 LIKE '%%'”也放回WHERE语句中时,一切又恢复了原状。于是新一轮的资料查找又开始了。但网上的资料似乎始终没有脱离以上3种语句的范围,在漫长的查找后我快要放弃了,忽然在一条论坛回复中我看见了新的曙光:用WHERE…IN语句。我立刻改写出了4号语句:

4.SELECT * FROM test 
   WHERE id IN (
      SELECT id FROM (
        SELECT id, ROWNUM AS rn FROM (
          SELECT id FROM test
          WHERE a1 LIKE '%%'
          ORDER BY id
        ) t1 WHERE  ROWNUM<=1000000
      ) t2 WHERE  rn>=999990 
    );

这条语句通过减少最内层SELECT语句获得的数据量(仅保留必须的id),极大地提高了查询性能。但是WHERE…IN语句由于需要遍历数据表,也就是说在本语句中每查询出一个id,Oracle就需要在最后的WHERE…IN语句搜索一次并把它挑出来,所以WHERE…IN语句本身的效率并不高,本语句依然存在着效率提升的空间,那么该怎么做呢?答案就是ROWID伪列。什么是ROWID伪列呢?用最简单的话说,ROWID就是该数据行的绝对物理地址,在百度百科上我们可以查到索引就是通过ROWID来记录数据位置的。于是我们的WHERE…IN语句不再需要遍历数据表,不再需要通过一次次的检索来收集数据了,因为它得到了最终数据的直接物理地址。从这个意义上讲,WHERE…IN语句成为了最高效的语句。
语句改写如下:

5.SELECT * FROM test 
   WHERE ROWID IN (
      SELECT rid FROM (
        SELECT rid, ROWNUM AS rn FROM (
          SELECT ROWID rid FROM test
          WHERE a1 LIKE '%%'
          ORDER BY id
        ) t1 WHERE  ROWNUM<=1000000
      ) t2 WHERE  rn>=999990 
    );

令人困惑的是,虽然5号语句检索出来的数据范围是正确的,但是最终的顺序是被打乱的,也就是说id虽然范围是在999990-1000000中,但相互间是没有顺序的,当然到这一步已经没有什么难度了,于是我写出了最终的语句:

6. SELECT * FROM test 
   WHERE ROWID IN (
      SELECT rid FROM (
        SELECT rid, ROWNUM AS rn FROM (
          SELECT ROWID rid FROM test
          WHERE a1 LIKE '%%'
          ORDER BY id
        ) t1 WHERE  ROWNUM<=1000000
      ) t2 WHERE  rn>=999990 
    ) ORDER BY id;
至此一切OK,为了对提升的效率有个直观的理解,我又对1、2、4、6号语句进行了测试(测试数据表test共1011003条记录),各测试三次去平均值,结果如下:

1号语句(两层嵌套,而且结果并不符合预期):21.98秒
2号语句(三层嵌套,结果符合预期,但实在是太慢了。。。):48.62秒
4号语句(采用WHERE id IN …,结果符合预期,效率极大提高):11.49秒
6号语句(采用WHERE ROWID IN …,结果符合预期,效率最高):5.98秒

以上是我对Oracle中分页排序查询语句执行效率的一点理解,如果有什么错误的地方请大家指正,谢谢!
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/730680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【动态规划算法】第八题:931.下降路径最小和

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法\&#x1f384; 如 果 你…

PqQt实现对数据库的添加,删除,修改(完整过程演示)

在PyQt中设置的如下的窗口&#xff1a; 其中的图标是通过新建Resource File加入的 images里面的图片可以在这里面取&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1gOgBpW7s-ZWn_5aRoaYLkQ 提取码&#xff1a;jyjy 我们把这个文件取名为res.qrc 资源文件的使用可以…

基于matlab显示城市街区场景中配备立体摄像机的无人机开发视觉SLAM算法(附源码)

一、前言 视觉SLAM是计算摄像机相对于周围环境的位置和方向&#xff0c;同时映射环境的过程。开发可视化 SLAM 算法并评估其在不同条件下的性能是一项具有挑战性的任务。最大的挑战之一是生成相机传感器的地面实况&#xff0c;尤其是在户外环境中。使用仿真可以在各种场景和相…

HarmonyOS学习路之开发篇—数据管理(分布式文件服务)

分布式文件服务概述 分布式文件服务能够为用户设备中的应用程序提供多设备之间的文件共享能力&#xff0c;支持相同帐号下同一应用文件的跨设备访问&#xff0c;应用程序可以不感知文件所在的存储设备&#xff0c;能够在多个设备之间无缝获取文件。 基本概念 分布式文件 分布…

WebGIS 信息系统-Element项目实战

WebGIS 信息系统-Element项目实战 Element的安装OpenLayers的安装采用直接引用的方式配置开发环境下载Vue文件下载Element文件下载OpenLayers文件 Element的安装 在项目的根目录中&#xff0c;首先按下 Shift鼠标右键&#xff0c;在弹出的右键菜单中选择“在此处打开命令行窗口…

OpenCV 的 remap 函数改变图像中像素的位置

#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #

Spring Boot 中的 @Scheduled 注解是什么,如何使用

Spring Boot 中的 Scheduled 注解是什么&#xff0c;如何使用 引言 Spring Boot 是一个非常流行的 Java Web 开发框架&#xff0c;它提供了很多方便的功能&#xff0c;其中就包括了 Scheduled 注解。本文将会介绍 Scheduled 注解的基本用法&#xff0c;并附上代码示例&#x…

2023 最新「阿里」Java 高级工程师面试高频题

7月份快要过去了&#xff0c;也意味着金九银十快到了&#xff0c;不知道大家有没有发现今年的面试比之前的都难&#xff1b;去年因为疫情的原因压抑住程序员跳槽的想法&#xff0c;再加上现在 IT 行业内卷越来越严重&#xff0c;这两点原因导致今年的招聘市场非常难受&#xff…

【模式识别目标检测】——基于机器视觉的无人机避障RP-YOLOv3实例

目录 引入 一、YOLOv3模型 1、实时目标检测YOLOv3简介 2、改进的实时目标检测模型 二、数据集建立&结果分析 1、数据集建立 2、模型结果分析 三、无人机避障实现 参考文献&#xff1a; 引入 目前对于障碍物的检测整体分为&#xff1a;激光、红外线、超声波、雷达、…

使用FAST方法检测特征点,然后计算这些特征点的ORB描述子,并使用暴力匹配方法找到匹配的特征点

这段代码主要做了以下几件事情: 读取两幅图像使用FAST方法找出图像中的特征点手写ORB方法计算特征点的描述子使用汉明距离(Hamming distance)进行描述子的匹配显示匹配的结果下面我们会逐行解释每一句代码: 包含头文件:这一部分包含了所有需要的库。 ComputeORB 函数:该函…

【验证码逆向专栏】某度滑块、点选、旋转验证码 v1、v2 逆向分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 本文章未…

SSL密钥算法检测工具-sslciphercheck-SSL/TLS Suffers ‘Bar Mitzvah Attack’漏洞

SSL密钥算法检测工具-sslciphercheck-SSL/TLS Suffers ‘Bar Mitzvah Attack’漏洞 文章目录 sslciphercheck漏洞&#xff1a;SSL/TLS Suffers ‘Bar Mitzvah Attack’漏洞漏洞描述漏洞检测修复建议 sslciphercheck 下载&#xff1a;https://github.com/woanware/woanware.git…

Ubuntu vim 以十六进制的形式显示文件内容

Vim的介绍 Vim&#xff08;Vi IMproved&#xff09;是一款开源的文本编辑器&#xff0c;是 Unix 系统中经典的 vi 编辑器的改进版本。它具有强大的功能和高度可定制性&#xff0c;被广泛应用于程序开发、系统管理和文本编辑等领域。 以下是 Vim 的一些主要特点和功能&#xf…

CRC Principle and Implementation Method(Java C)

CRC原理和程序实现方法1_哔哩哔哩_bilibili 其实原理很简单 但是我想了两个小时。。 收获的是原来一些复杂的运算都可以通过位运算来实现。 实现思路 public class CRC16Calculator {public static String CRC16(byte[] bytes) {int CRC 0x0000ffff;int POLYNOMIAL 0x0000a…

【复习3-5天的内容】【我们一起60天准备考研算法面试(大全)-第七天 7/60】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

Ubuntu Linux系统下创建Git项目并push到远程Github

首先在本地创建git仓库 jasminelhl:~/prj$ mkdir Github-test jasminelhl:~/prj$ cd Github-test jasminelhl:~/prj/Github-test$ git init 提示&#xff1a;使用 master 作为初始分支的名称。这个默认分支名称可能会更改。要在新仓库中 提示&#xff1a;配置使用初始分支名&a…

RabbitMQ的可视化管理页面简介

模块 描述 Overview 概览 Connections 查看连接情况 Channels 信道(通过)情况 Exchanges 交换机(路由)情况,默认四类七个 Queues 消息队列情况 Admin …

高并发架构实战:从需求分析到系统设计

很多软件工程师的职业规划是成为架构师&#xff0c;但是要成为架构师很多时候要求先有架构设计经验&#xff0c;而不做架构师又怎么会有架构设计经验呢&#xff1f;那么要如何获得架构设计经验呢&#xff1f; 一方面可以通过工作来学习&#xff0c;观察所在团队的架构师是如何…

网络安全工程师工作内容具体是什么?

在知乎看到一个帖子&#xff1a;网络安全工程师或者网络安全研究员的工作内容具体是什么&#xff1f;或者说他们的一天具体是怎么度过的&#xff0c;是否和程序员一样编码做项目&#xff1f; Neeao的回复&#xff1a; 只在甲方互联网公司呆过&#xff0c;简单说下甲方的情况。…

“千模千测”——针对大语言模型认知能力的高效测试方法

©PaperWeekly 原创 作者 | 庄严、宁雨亭 单位 | 中国科学技术大学BASE课题组 论文标题&#xff1a; Efficiently Measuring the Cognitive Ability of LLMs: An Adaptive Testing Perspective 作者&#xff1a; Yan Zhuang, Qi Liu, Yuting Ning, Weizhe Huang, Rui Lv, …