分页 订阅
分页(英语:Paging),是一种操作系统里存储器管理的一种技术,可以使电脑的主存可以使用存储在辅助存储器中的数据。操作系统会将辅助存储器(通常是磁盘)中的数据分区成固定大小的区块,称为“页”(pages)。当不需要时,将分页由主存(通常是内存)移到辅助存储器;当需要时,再将数据取回,加载主存中。相对于分段,分页允许存储器存储于不连续的区块以维持文件系统的整齐。分页是磁盘和内存间传输数据块的最小单位。 展开全文
分页(英语:Paging),是一种操作系统里存储器管理的一种技术,可以使电脑的主存可以使用存储在辅助存储器中的数据。操作系统会将辅助存储器(通常是磁盘)中的数据分区成固定大小的区块,称为“页”(pages)。当不需要时,将分页由主存(通常是内存)移到辅助存储器;当需要时,再将数据取回,加载主存中。相对于分段,分页允许存储器存储于不连续的区块以维持文件系统的整齐。分页是磁盘和内存间传输数据块的最小单位。
信息
外文名
Paging
领    域
计算机
定    义
一种操作系统里存储器管理的技术
中文名
分页
性    质
磁盘和内存间传输数据块最小单位
学    科
计算机
分页简介
分页(英语:Paging),是一种操作系统里存储器管理的一种技术,可以使电脑的主存可以使用存储在辅助存储器中的数据。操作系统会将辅助存储器(通常是磁盘)中的数据分区成固定大小的区块,称为“页”。当不需要时,将分页由主存(通常是内存)移到辅助存储器;当需要时,再将数据取回,加载主存中。相对于分段,分页允许存储器存储于不连续的区块以维持文件系统的整齐。分页是磁盘和内存间传输数据块的最小单位。分页/虚拟内存能有助“大大地”降低整体及额外非必要的 I/O 次数,提高系统整体运作性能。因为这能有助提高 RAM 的读取命中率,也透过其内部的高效率算法来达到 I/O 数据流的预缓存工作,通过与之相关的等等手段也能很好地提高了 CPU 的使用效率,而拥有大物理内存的用户更可能考虑利用如Ramdisk、Supercache、SoftPerfect RAM Disk等模拟出硬盘分区来同时将虚拟内存/系统临时文件等设置其上以进一步加强系统性能,及达至保障硬盘的措施。分页是虚拟内存技术中的重要部分。
收起全文
精华内容
参与话题
问答
  • 分页查询

    万次阅读 多人点赞 2014-02-22 19:55:32
    分页查询,就是将将过多的结果在有限的界面上分好多页来显示,这个是很多网站常用的功能,也是最基本的功能,今天简单总结一下。  分页以前听人们说都是一项技术,但是我觉的不尽然。我认为分页是将数据库的数据...

             分页查询,就是将将过多的结果在有限的界面上分好多页来显示,这个是很多网站常用的功能,也是最基本的功能,今天简单总结一下。


              分页以前听人们说都是一项技术,但是我觉的不尽然。我认为分页是将数据库的数据,利用一些特殊的sql语句来进行查询,显示理所应当显示的内容,更恰当的说可以是对SQL语句的灵活运用,对逻辑思维的简单使用。


             一,一般人们将分页查询分为两类:逻辑分页,物理分页,我们先从理论上理解一下:

                 1,逻辑分页概述:就是用户第一次访问时,将数据库的所有记录全部查询出来,添加到一个大的集合中,然后存放在session对象,然后通过页码计算出当前页需要显示的数据内容,存储到一个小的list的集合中,并将之存储到request对象中,跳转到JSP页面,进行遍历显示。 当用户第二次访问时,只要不关闭浏览器,我们还会从session中获取数据,来进行显示。为什么叫逻辑分页呢?因为此种方法是在内存的session对象中进行计算分页显示的,而不是真正的将我们数据库进行分页的。

            来看它的一些缺点吧:

                  a,如果需要查询的数据量过大,session将耗费大量的内存;

                  b,因为是在session中获取数据,如果第二次或者更多此的不关闭浏览器访问,会直接访问session,从而不能保证数据是最新的。

            小结:这种分页很少使用。但是在数据量小,不会被修改的数据,使用逻辑分页会提高程序的执行效率。

     

               2,物理分页概述:使用数据库自身所带的分页机制,例如,Oracle数据库的rownum,或者Mysql数据库中的limit等机制来完成分页操作。因为是对数据库实实在在的数据进行分页条件查询,所以叫物理分页。每一次物理分页都会去连接数据库。

                优点:数据能够保证最新,由于根据分页条件会查询出少量的数据,所以不会占用太多的内存。

                缺点:物理分页使用了数据库自身带的机制,所以这样的SQL语句不通用,导致不能进行数据库的移植。

               小结:在实际中物理分页还是使用的较多的。

     


      二,看一下逻辑分页查询的应用:


    	public class PageQueryUserServlet extends HttpServlet {
    	
    		@Override
    		protected void doGet(HttpServletRequest request, HttpServletResponse response)
    				throws ServletException, IOException {
    			
    			//获取页码
    			int pageno = Integer.parseInt(request.getParameter("pageno")==null?"1":request.getParameter("pageno")); 
    			
    			
    			//从session中获取大List集合
    			HttpSession session = request.getSession();
    			List<User> bigList = (List<User>)session.getAttribute("bigList");
    			
    			//如果第一次访问
    			if(bigList == null){
    				
    				//创建大List集合
    				bigList = new ArrayList<User>();
    				
    				//如果大List集合不存在,则连接数据库
    				Connection conn = null;
    				PreparedStatement ps= null;
    				ResultSet rs = null;
    				try {
    					conn = DBUtil.getConnection();
    					String sql = "select usercode,username,orgtype from t_user order by regdate desc";
    					ps = conn.prepareStatement(sql);
    					
    					//执行查询语句返回查询结果集
    					rs = ps.executeQuery();
    					
    					//遍历结果集封装javabean对象并存储到大List集合中
    					while(rs.next()){
    						User user = new User();
    						user.setUsercode(rs.getString("usercode"));
    						user.setUsername(rs.getString("username"));
    						user.setOrgtype(rs.getString("orgtype"));
    						bigList.add(user);
    					}
    					
    					//将大List集合存储到session中
    					session.setAttribute("bigList", bigList);
    					
    				} catch (Exception e) {
    					e.printStackTrace();
    				} finally{
    					DBUtil.close(conn, ps, rs);
    				}
    			}
    			
    			
    			//如果从session中可以获取到大List集合,则通过页码计算得出小List集合
    			List<User> smallList = new ArrayList<User>();
    			
    			//计算开始标识=页数大小*(页码-1)
    			int beginIndex = Const.PAGE_SIZE * (pageno-1);
    			
    			//结束标识=页数大小*页码,如果超过了总数据条数,则表示为最后一页,写为总结条数即可
    			int endIndex = Const.PAGE_SIZE * pageno > bigList.size() ? bigList.size() : Const.PAGE_SIZE * pageno;
    			
    			for(int i=beginIndex;i<endIndex;i++){
    				smallList.add(bigList.get(i));
    			}
    			
    			//将小List集合存储到request对象中
    			request.setAttribute("userList", smallList);
    			
    			//转发
    		}
    		
    
    }



              三,好,物理分页和逻辑分页的计算方法差不多,只不过一个是session中一个是在数据库中,这里物理分页总结一下多条件查询分页显示的过程,这里也将分页对象进行封装了:

                先看一下分页对象的编写:

    	/**
    	 * 分页对象
    	 * @author Administrator
    	 */
    	public class Page<T> {
    		/**
    		 * 页码
    		 */
    		private int pageno;
    		
    		/**
    		 * 每页显示的记录条数
    		 */
    		private int pagesize;
    		
    		/**
    		 * 数据集合(需要显示在网页中的数据)
    		 */
    		private List<T> dataList;
    		
    		/**
    		 * 总记录条数
    		 */
    		private int totalsize;
    		
    		
    		public Page(String pageno) {
    			this.pageno = (pageno == null ? 1 : Integer.parseInt(pageno));
    			this.pagesize = Const.PAGE_SIZE;
    			this.dataList = new ArrayList<T>();
    		}
    		
    		public int getPageno(){
    			return pageno;
    		}
    		
    		public int getPagesize(){
    			return pagesize;
    		}
    		
    		public List<T> getDataList(){
    			return dataList;
    		}
    		
    		public void setTotalsize(int totalsize){
    			this.totalsize = totalsize;
    		}
    		
    		public int getTotalsize(){
    			return totalsize;
    		}
    		
    		public int getPagecount(){
    			return totalsize%pagesize == 0 ? totalsize/pagesize : totalsize/pagesize + 1;
    		}
    		
    		/**
    		 * 通过业务SQL语句获取分页SQL语句
    		 * @param sql 业务SQL
    		 * @return 分页SQL语句
    		 * 这是非常核心的,通过多次嵌套,嵌套出分页sql语句的编写
    		 */
    		public String getSql(String sql){
    			return "select t1.* from (select t.*,rownum as linenum from ("+sql+") t where rownum<=" + pageno*pagesize + ") t1 where t1.linenum>" + (pageno-1)*pagesize;
    		}
    	}
    

     有了这个分页对象,我就可以利用它了,看我们动态参数分页查询的过程,重点看注释步骤:

    	/**
    	 * 动态参数查询,难度最大的是SQL语句动态拼接。(因为查询提交内容不定,查询提交个数不定)
    	 * @author Administrator
    	 */
    	public class PageQueryInvServlet extends HttpServlet {
    	
    		@Override
    		protected void doPost(HttpServletRequest request, HttpServletResponse response)
    				throws ServletException, IOException {
    			
    			//解决请求体的中文乱码问题
    			//request.setCharacterEncoding("GB18030");
    			
    			//创建分页对象
    			Page<Investor> page = new Page<Investor>(request.getParameter("pageno"));
    			
    			//获取查询提交的数据
    			String invregnum = request.getParameter("invregnum");
    			String invname = request.getParameter("invname");
    			String startdate = request.getParameter("startdate");
    			String enddate = request.getParameter("enddate");
    			
    			//拼接业务SQL,注意其中的技巧,where 1=1,另外这里使用StringBuilder提高拼接的效率
    			StringBuilder sql = new StringBuilder("select i.invregnum,i.invname,i.regdate,u.username,i.cty from t_invest i join t_user u on i.usercode=u.usercode where 1=1");
    			StringBuilder totalsizeSql = new StringBuilder("select count(*) as totalsize from t_invest i join t_user u on i.usercode=u.usercode where 1=1");
    			//创建list集合用来绑定下标和内容,利用的list下标和值对应关系的特点
    			List<String> paramList = new ArrayList<String>();
    			
    			//动态参数拼接动态SQL语句
    			if(StringUtil.isNotEmpty(invregnum)){
    				sql.append(" and i.invregnum = ?");
    				totalsizeSql.append(" and i.invregnum = ?");
    				paramList.add(invregnum); 
    			}
    			
    			if(StringUtil.isNotEmpty(invname)){
    				sql.append(" and i.invname like ?");
    				totalsizeSql.append(" and i.invname like ?");
    				paramList.add("%" + invname + "%"); 
    			}
    			
    			if(StringUtil.isNotEmpty(startdate)){
    				sql.append(" and i.regdate >= ?");
    				totalsizeSql.append(" and i.regdate >= ?");
    				paramList.add(startdate); 
    			}
    			
    			if(StringUtil.isNotEmpty(enddate)){
    				sql.append(" and i.regdate <= ?");
    				totalsizeSql.append(" and i.regdate <= ?");
    				paramList.add(enddate); 
    			}
    			
    			//调用获取分页SQL
    			String pageSql = page.getSql(sql.toString());
    			
    			//连接数据库查询数据
    			Connection conn = null;
    			PreparedStatement ps = null;
    			ResultSet rs = null;
    			try {
    				conn = DBUtil.getConnection();
    				ps = conn.prepareStatement(pageSql);
    				
    				//给?赋值(重点),这里list的巧妙使用
    				for(int i=0;i<paramList.size();i++){
    					ps.setString(i+1, paramList.get(i));
    				}
    				
    				//执行查询语句,返回查询结果集
    				rs = ps.executeQuery();
    				
    				//遍历结果集,每遍历一次,封装Investor对象,将其添加到List集合中
    				while(rs.next()){
    					Investor inv = new Investor();
    					inv.setInvregnum(rs.getString("invregnum"));
    					inv.setInvname(rs.getString("invname"));
    					inv.setRegdate(rs.getString("regdate"));
    					inv.setUsername(rs.getString("username"));
    					inv.setCty(rs.getString("cty"));
    					
    					page.getDataList().add(inv);
    				}
    				
    				//查询总记录条数,并且设置到分页对象中
    				ps = conn.prepareStatement(totalsizeSql.toString());
    				
    				//给?赋值
    				for(int i=0;i<paramList.size();i++){
    					ps.setString(i+1, paramList.get(i));
    				}
    				
    				rs = ps.executeQuery();
    				
    				if(rs.next()){
    					page.setTotalsize(rs.getInt("totalsize"));
    				}
    				
    			} catch (Exception e) {
    				e.printStackTrace();
    			} finally{
    				DBUtil.close(conn, ps, rs);
    			}
    			
    			//将分页对象存储到request范围中
    			request.setAttribute("pageObj", page);
    			
    			//转发
    		     
    		}
    		
    	}
    



              分页查询将数据量分成几批显示到页面上。就像我们的书本,这不过这里的动态,可能因为查询条件的不同,页面的内容就不同,所以灵活应用,弄清楚查询条件,编写好分页查询语句,那么什么问题都解决了。

    展开全文
  • MyBatis-Plus 分页查询以及自定义sql分页

    万次阅读 多人点赞 2019-06-12 17:53:46
    分页查询每个人程序猿几乎都使用过,但是有部分同学不懂什么是物理分页和逻辑分页。 物理分页:相当于执行了limit分页语句,返回部分数据。物理分页只返回部分数据占用内存小,能够获取数据库最新的状态,实施性...

    一、引言

    分页查询每个人程序猿几乎都使用过,但是有部分同学不懂什么是物理分页和逻辑分页。

    物理分页:相当于执行了limit分页语句,返回部分数据。物理分页只返回部分数据占用内存小,能够获取数据库最新的状态,实施性比较强,一般适用于数据量比较大,数据更新比较频繁的场景。

    逻辑分页:一次性把全部的数据取出来,通过程序进行筛选数据。如果数据量大的情况下会消耗大量的内存,由于逻辑分页只需要读取数据库一次,不能获取数据库最新状态,实施性比较差,适用于数据量小,数据稳定的场合。

    那么MP中的物理分页怎么实现呢? 往下看往下看

    二、配置

    创建MybatisPlusConfig配置类,需要配置分页插件,小编使用的Spring boot配置方式。

    /**
     * @Auther: IT贱男
     * @Date: 2019/6/12 15:06
     * @Description: MybatisPlus配置类
     */
    @Configuration
    public class MyBatisPlusConfig {
    
        /**
         * 分页插件
         * @return
         */
        @Bean
        public PaginationInterceptor paginationInterceptor() {
            return new PaginationInterceptor();
        }
    }

    三、具体分页实现

    MP的Wrapper提供了两种分页查询的方式,源码如下

        /**
         * 根据 entity 条件,查询全部记录(并翻页)
         *
         * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    
        /**
         * 根据 Wrapper 条件,查询全部记录(并翻页)
         *
         * @param page         分页查询条件
         * @param queryWrapper 实体对象封装操作类
         */
        IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    可见两个分页方法参数都是一致的,只是返回参数略有不同,具体选择根据实际业务为准。

        /**
         * 分页查询
         */
        @Test
        public void selectByPage() {
            QueryWrapper<User> wrapper = new QueryWrapper();
            wrapper.like("name", "雨").lt("age", 40);
    
            Page<User> page = new Page<>(1,2);
    
            //IPage<User> userIPage = userMapper.selectPage(page, wrapper);
    
            IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, wrapper);
    
    
            System.out.println("总页数"+mapIPage.getPages());
            System.out.println("总记录数"+mapIPage.getTotal());
            List<Map<String, Object>> records = mapIPage.getRecords();
            records.forEach(System.out::println);
        }

    以上分页查询执行sql如下,先是查询了一次总记录数,然后在查询的数据。

    DEBUG==>  Preparing: SELECT COUNT(1) FROM user WHERE name LIKE ? AND age < ? 
    DEBUG==> Parameters: %雨%(String), 40(Integer)
    TRACE<==    Columns: COUNT(1)
    TRACE<==        Row: 2
    DEBUG==>  Preparing: SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age < ? LIMIT ?,? 
    DEBUG==> Parameters: %雨%(String), 40(Integer), 0(Long), 2(Long)
    TRACE<==    Columns: id, name, age, email, manager_id, create_time
    TRACE<==        Row: 2, 张雨琪, 31, zjq@baomidou.com, 1088248166370832385, 2019-01-14 09:15:15
    TRACE<==        Row: 3, 刘红雨, 31, lhm@baomidou.com, 1088248166370832385, 2019-01-14 09:48:16
    DEBUG<==      Total: 2
    总页数1
    总记录数2

    现在我们有需求只要查询数据即可, 不关心总记录数等,如果使用默认的方式就消耗不必要的性能。那么解决办法也是很简单的,只需要在创建page对象时传入第三个参数为false即可

     Page<User> page = new Page<>(1,2,false);

    四、自定义sql分页查询

    有时候查询的数据难免会出现多表连接查询,或者是一些复杂的sql语句,但是这些语句也是需要支持分页查询的,

    先定义查询接口,第一个参数要是分页的参数,小编这里演示就写简单的sql。

    步骤一:在mapper文件中,编写对应的分页查询接口。

    步骤二:在xml中编写对应的sql语句,小编这里演示的 “${ew.customSqlSegment}”,这个是如果你想自定义的sql语句,也想使用wrapper查询条件构造器,则需要在mapper接口中添加参数,以及xml中也要有固定。 

        /**
         * 自定义sql分页
         * @param page
         * @param queryWrapper 看这里看这里,如果自定义的方法中需要用到wrapper查询条件,需要这样写
         * @return
         */
        IPage<User> selectMyPage(IPage<User> page, @Param(Constants.WRAPPER) Wrapper<User> queryWrapper);
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.demo.mapper.UserMapper">
    
        <select id="selectMyPage" resultType="com.example.demo.model.User">
            SELECT * FROM user ${ew.customSqlSegment}
        </select>
    
    </mapper>
       /**
         * 自定义sql分页查询
         */
        @Test
        public void selectByMyPage() {
            QueryWrapper<User> wrapper = new QueryWrapper();
            wrapper.like("name", "雨").lt("age", 40);
            Page<User> page = new Page<>(1,2);
            IPage<User> mapIPage = userMapper.selectMyPage(page, wrapper);
    
            System.out.println("总页数"+mapIPage.getPages());
            System.out.println("总记录数"+mapIPage.getTotal());
            List<User> records = mapIPage.getRecords();
            records.forEach(System.out::println);
        }

    五、多表sql分页查询

    看评论有小伙伴反馈多表连接查询怎么分页,其实道理都是一样的。

    小编以简单的为主,sql如下: his_ipd_encounter、his_user 两张表

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.demo.mapper.UserMapper">
    
        <select id="selectByHisName" resultType="java.lang.String">
            select u.realname from his_ipd_encounter e, his_user u where e.his_uid = u.his_uid
        </select>
        
    
    </mapper>

    mapepr如下:需要传入分页的参数,返回的类型也需要是分页对象

    
    /**
     * <p>
     * 用户 Mapper 接口
     * </p>
     *
     * @author IT贱男
     * @since 2019-06-14
     */
    public interface UserMapper extends MyMapper<User> {
    
    
        /**
         * 多表查询分页
         * @param page
         * @return
         */
        IPage<String> selectByHisName(IPage<User> page);
    }
    

    测试如下:通过查看日志,执行的sql加了分页条件的。

       @Test
        public void select(){
            // 创建分页参数
            Page<User> page = new Page<>(1,2);
            IPage<String> result = userMapper.selectByHisName(page);
            // 获取数据
            List<String> records = result.getRecords();
            records.forEach(System.out::println);
            System.out.println("总页数 = "+ result.getPages());
        }
    
    ARNWarn: Could not find @TableId in Class: com.example.demo.model.HisUser.
    INFOStarted UserMapperTest in 2.428 seconds (JVM running for 2.959)
    select u.realname from his_ipd_encounter e, his_user u where e.his_uid = u.his_uid
    DEBUG==>  Preparing: SELECT COUNT(1) FROM his_ipd_encounter e, his_user u WHERE e.his_uid = u.his_uid 
    DEBUG==> Parameters: 
    TRACE<==    Columns: COUNT(1)
    TRACE<==        Row: 117
    DEBUG==>  Preparing: select u.realname from his_ipd_encounter e, his_user u where e.his_uid = u.his_uid LIMIT ?,? 
    DEBUG==> Parameters: 0(Long), 2(Long)
    TRACE<==    Columns: realname
    TRACE<==        Row: 胡伯云
    TRACE<==        Row: 安元慧
    DEBUG<==      Total: 2
     Time:20 ms - ID:com.example.demo.mapper.UserMapper.selectByHisName
    Execute SQL:
        com.p6spy.engine.wrapper.PreparedStatementWrapper@61bcbcce
    
    胡伯云
    安元慧
    总页数 = 59
    

     

    展开全文
  • 【mySQL】mysql 分页查询

    万次阅读 多人点赞 2019-05-05 14:36:37
    MySQL:limit分页公式、总页数公式 1) limit分页公式 (1)limit分页公式:curPage是当前第几页;pageSize是一页多少条记录 limit (curPage-1)*pageSize,pageSize (2)用的地方:sql语句中 select * from student...

    目录

    一、limit分页公式、总页数公式

    1 limit分页公式

    2 总页数公式

    二 、Mysql的三种分页方法

    1 limit m,n分页语句

    2 limit m语句

    三、 查询优化

    1 使用子查询优化

    2 使用 id 限定优化(前提:id是连续递增,删除过记录不符合)

    3 使用临时表优化

    四、关于数据表的id说明


    一、limit分页公式、总页数公式


    1 limit分页公式


    (1)limit分页公式:curPage是当前第几页;pageSize是一页多少条记录

    limit  (curPage-1)*pageSize,pageSize

    (2)用的地方:sql语句中

    select * from student limit(curPage-1)*pageSize,pageSize;

    2 总页数公式


    (1)总页数公式:totalRecord是总记录数;pageSize是一页分多少条记录

    int totalPageNum = (totalRecord +pageSize - 1) / pageSize;

    (2)用的地方:前台UI分页插件显示分页码
    (3)查询总条数:totalRecord是总记录数,SELECT COUNT(*) FROM tablename


    二 、Mysql的三种分页方法

     

    1 limit m,n分页语句

    select * from dept order by deptno desc limit 3,3;
    select * from dept order by deptno desc limit m,n;

    limit 3,3的意思扫描满足条件的3+3行,撇去前面的3行,返回最后的3行,那么问题来了,如果是limit 200000,200,需要扫描200200行,如果在一个高并发的应用里,每次查询需要扫描超过20W行,效率十分低下。

    测试见:https://www.cnblogs.com/youyoui/p/7851007.html

    例如:

    select * from orders_history where type=8 limit 100,100;
    select * from orders_history where type=8 limit 1000,100;
    select * from orders_history where type=8 limit 10000,100;
    select * from orders_history where type=8 limit 100000,100;
    select * from orders_history where type=8 limit 1000000,100;


    2 limit m语句

     select * from dept where deptno >10 order by deptno asc limit n;//下一页
     select * from dept where deptno <60 order by deptno desc limit n//上一页

    这种方式不管翻多少页只需要扫描n条数据。

    但是,虽然扫描的数据量少了,但是在某些需要跳转到多少也得时候就无法实现,这时还是需要用到方法1,既然不能避免,那么我们可以考虑尽量减小m的值,因此我们可以给这条语句加上一个条件限制。是的每次扫描不用从第一条开始。这样就能尽量减少扫描的数据量。

    例如:每页10条数据,当前是第10页,当前条目ID的最大值是109,最小值是100.(当前100-109)
    那么跳到第9页:

    select * from dept where deptno<100 order by deptno desc limit 0,10;   //倒序

    那么跳到第8页:

    select * from dept where deptno<100 order by deptno desc limit 10,10;

    那么跳到第11页:

    select * from dept where deptno>109 order by deptno asc limit 0,10;


    最后附上参考文档网址:http://www.open-open.com/doc/view/2bda32bf64864e8e965e91686f5309d4
    原文:https://blog.csdn.net/HADEWOKE/article/details/53996110

    上面的方法还可以优化,见第三。

    三、 查询优化

    子查询优化原理:https://zhuanlan.zhihu.com/p/163658548

    1 使用子查询优化

    这种方式先定位偏移位置的 id,然后往后查询,这种方式适用于 id 递增的情况。

    select * from orders_history where type=8 limit 100000,1;
    select id from orders_history where type=8 limit 100000,1;
    
    select * from orders_history where type=8 and 
    id>=(select id from orders_history where type=8 limit 100000,1) 
    limit 100;
    
    select * from orders_history where type=8 limit 100000,100;
    

    4条语句的查询时间如下:

    • 第1条语句:3674ms
    • 第2条语句:1315ms
    • 第3条语句:1327ms
    • 第4条语句:3710ms

    针对上面的查询需要注意:

    • 比较第1条语句和第2条语句:使用 select id 代替 select * 速度增加了3倍
    • 比较第2条语句和第3条语句:速度相差几十毫秒
    • 比较第3条语句和第4条语句:得益于 select id 速度增加,第3条语句查询速度增加了3倍

    这种方式相较于原始一般的查询方法,将会增快数倍。

     

     

    2 使用 id 限定优化(前提:id是连续递增,删除过记录不符合)

    这种方式假设数据表的id是连续递增的,则我们根据查询的页数和查询的记录数可以算出查询的id的范围,可以使用 id between and 来查询:

    select * from orders_history where type=2 
    and id between 1000000 and 1000100 limit 100;
    

    查询时间:15ms 12ms 9ms

    这种查询方式能够极大地优化查询速度,基本能够在几十毫秒之内完成。限制是只能使用于明确知道id的情况,不过一般建立表的时候,都会添加基本的id字段,这为分页查询带来很多便利。

    还可以有另外一种写法:

    select * from orders_history where id >= 1000001 limit 100;
    

    当然还可以使用 in 的方式来进行查询,这种方式经常用在多表关联的时候进行查询,使用其他表查询的id集合,来进行查询:

    select * from orders_history where id in
    (select order_id from trade_2 where goods = 'pen')
    limit 100;
    

    这种 in 查询的方式要注意:某些 mysql 版本不支持在 in 子句中使用 limit。

    3 使用临时表优化

    这种方式已经不属于查询优化,这儿附带提一下。

    对于使用 id 限定优化中的问题,需要 id 是连续递增的,但是在一些场景下,比如使用历史表的时候,或者出现过数据缺失问题时,可以考虑使用临时存储的表来记录分页的id,使用分页的id来进行 in 查询。这样能够极大的提高传统的分页查询速度,尤其是数据量上千万的时候。

     

    四、关于数据表的id说明

    一般情况下,在数据库中建立表的时候,强制为每一张表添加 id 递增字段,这样方便查询。

    如果像是订单库等数据量非常庞大,一般会进行分库分表。这个时候不建议使用数据库的 id 作为唯一标识,而应该使用分布式的高并发唯一 id 生成器来生成,并在数据表中使用另外的字段来存储这个唯一标识。

    使用先使用范围查询定位 id (或者索引),然后再使用索引进行定位数据,能够提高好几倍查询速度。即先 select id,然后再 select *;

    https://www.cnblogs.com/youyoui/p/7851007.html

     

    展开全文
  • redis实现分页查询

    万次阅读 2019-04-01 21:20:50
    人工智能,零基础入门!... redis中的一个数据类型:list list用于存放类似粉丝列表、文章...list类型实现数据分页查询,通过lrange命令,读取某个闭区间内的元素,如下: # 0开始位置 3结束位置 lrange mylist 0 3 ...

    人工智能,零基础入门!http://www.captainbed.net/inner

    redis中的一个数据类型:list

    list用于存放类似粉丝列表、文章的评论列表之类的东西,
    list类型实现数据分页查询,通过lrange命令,读取某个闭区间内的元素,如下:
    # 0开始位置 3结束位置
    lrange mylist 0 3

    展开全文
  • ORACLE分页查询

    千次阅读 2018-06-27 11:22:45
    ORACLE分页查询 转自:ORACLE分页查询SQL语法——最高效的分页 无ORDER BY排序的写法。(效率最高) 经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然! ...
  • solr分页查询

    万次阅读 2017-06-14 14:59:26
    分页查询: package com.solorj.solrj_test; import java.io.IOException; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; import org.apache....
  • oracle分页查询

    千次阅读 2015-06-29 16:01:40
    oracle分页查询。 查询第6条到第10条数据:rownum相当于系统给分配的一列。 图中第二种方式效率更高一些。
  • ORACLE分页查询SQL语句(最有效的分页)

    万次阅读 多人点赞 2018-11-01 16:18:24
    ** 一、效率高的写法 ** 1.无ORDER BY排序的写法。...即使查询的数据量再大,也几乎不受影响,速度依然!) SELECT * FROM (SELECT ROWNUM AS rowno, t.* FROM emp t WHERE hire_date BETWEEN TO_DATE ...
  • 最近公司项目用到Elasticsearch,自己摸索了好几天才把这个弄明白,和大家分享一下: 一、建立Elasticsearch连接 package com.wlsj.yshj.config; import org.apache.http.HttpHost;...impor...
  • MySQL高效分页:子查询分页

    千次阅读 2013-11-08 15:44:26
    MySQL高效分页:子查询分页 正文:   一般MYSQL最基本的分页方式: select * from content order by id desc limit 0, 10 在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的...
  • mybatis分页查询

    千次下载 热门讨论 2015-12-28 00:04:59
    mybatis分页查询,spring + maven + mybatis实现分页查询源码
  • Java分页查询&条件查询

    万次阅读 2017-02-24 10:28:18
    1 分页查询 1.1 分页核心 设计一个用于封装当前页所有分页相关的数据的对象,叫分页对象PageBean /** * 分页对象。用于封装当前页的分页相关的所有数据 * @author h * */ public class PageBean { private List...
  • JPA分页查询与条件分页查询

    千次阅读 2019-05-06 00:02:00
    JPA分页查询与条件分页查询 情有独钟的JPA 平时在写一些小项目时,比较喜欢引用 Spring Data Jpa,其实还是图他写代码快~在日常的开发工作中,分页列表查询基本是随处可见,下面一起看一下如何...
  • JPA分页多条件查询分页联表查询

    千次阅读 2018-04-23 17:15:21
    一、分页多条件查询–重写Specification的toPredicate方法 Spring Data JPA支持JPA2.0的Criteria查询,相应的接口是JpaSpecificationExecutor。 Criteria 查询:是一种类型安全和更面向对象的查询 。 这个接口...
  • 分页查询:前端分页和后端分页

    千次阅读 2018-12-17 17:06:28
    1.废话 因为一次查出所有的数据太耗时,网络传输量也大,所以分页。 后端分页: 查询出指定条数的数据,在SQL中使用limit size, size * ... //设置分页查询得到数据  if(crl.size()&gt;=size*num){  ...
  • Mybatis实现真正分页查询

    万次阅读 2015-08-23 20:25:54
    Mybatis实现真正分页查询 MyBatis 本身是有分页查询的但是并不是真正的分页查询。它是先把数据查出来放在内存里面你要什么给你什么。 和真正的分页查询还是不一样的。如果数据太多的话。内存肯定会溢出的。那么...
  • 菜鸟学Java——分页查询

    万次阅读 多人点赞 2013-08-21 07:57:47
    今天继续跟大家说说一些非常基础的东西,这次我们说说分页查询。说到分页,可能很多人都听说过什么真分页、假分页的。简单解释一下,拿第二页,每页20条为例:真分:数据库里取 的就是21-40条;假分:数据库取出所有的,...
  • elasticsearch分页查询

    万次阅读 2015-12-14 22:51:59
    新博客地址主要有两种方式from/sizefrom 偏移,默认为0size 返回的结果数,默认为10在数据量不大的情况下我们一般会使用from/size,而在深度分页的情况下效率极低,该命令会把from+size条记录全部加在到内存中,对...
  • mongodb查询分页优化

    千次阅读 2013-09-09 13:55:27
    避免使用skip+limit的方式 前提:1.时间倒序排列(自己现在的项目中也是按照时间倒序...查询形式为 db.find(query).sort(time,-1).limit(limit)方式 注:query是查询条件,其中包括了时间段的条件,例如 a= 1)记录
  • SQL2005分页查询

    千次阅读 2011-04-20 17:33:00
    1 通过select top进行分页查询 2通过系统存储过程进行分页查询 3 通过新函数ROW_NUMBER()进行分页查询
  • Spring Data 查询分页 -- 分页请求参数

    千次阅读 2018-11-04 12:02:45
    针对查询的分页请求和分页结果的返回,Spring 提供了相应的建模...Pageable – 分页查询参数的接口抽象建模 Pageable接口是对分页查询参数的接口抽象建模,他主要包含以下三个基础信息: pageNumber – 当前页码,0...
  • Spring Data 查询分页 -- 分页结果返回

    千次阅读 2018-11-05 12:14:16
    针对数据查询中的分页请求参数和分页结果返回,Spring 做了建模抽象并提供了相应的工具实现,这部分模型和工具包含在包spring-data-commons中,本文对其中分页结果返回部分做一下梳理,方便在开发中使用 。...
  • MyBatis Plus 实现多表分页查询

    万次阅读 多人点赞 2019-07-08 17:25:52
    接口帮我们定义了很多常用的方法,但这些都是 T 对象有用,如果涉及到 多表的查询,还是需要自定义Vo 对象和自己编写sql 语句,Mybatis Plus提供了一个Page 对象,查询是需要设置其中的 size 字段 和 current 字段的...
  • mysql分页查询

    万次阅读 2018-12-25 17:31:38
    mysql分页查询 #分页查询 /* 应用场景:当要显示的数据,一页显示不全,需要分页提交sql请求 语法: select 查询列表 from 表 【join type join 表2 on 连接条件 where 筛选条件 group by 分组字段 having ...
  • Hibernate HQL查询 分页查询 模糊查询

    万次阅读 2011-12-21 09:42:06
    小记: Java代码  String hql="from WifiTTerminal where 1=1";   hql=hql+" and pws like '%'"+pws1+  "'%' and useStatus like '%'"+..."'%' and num like '%'"+num1+
  • 分页查询】Page如何做到分页查询

    千次阅读 2017-08-23 20:07:47
    分页查询是一个非常重要的知识点; 这里的代码不能直接拷贝运行,这里讲的只是个思路;public PageModel<UserList > selectCheckList (UserList userList) throws Exception{ PageHelper.startPage(searchVo....
  • pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation...

空空如也

1 2 3 4 5 ... 20
收藏数 159,639
精华内容 63,855
关键字:

分页