iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >sqlserver2005的分页优化
  • 919
分享到

sqlserver2005的分页优化

2024-04-02 19:04:59 919人浏览 独家记忆
摘要

这篇文章主要介绍“sqlserver2005的分页优化”,在日常操作中,相信很多人在sqlserver2005的分页优化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”sqls

这篇文章主要介绍“sqlserver2005的分页优化”,在日常操作中,相信很多人在sqlserver2005的分页优化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”sqlserver2005的分页优化”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!


一、hibernate分页 hibernate对MsSql的伪分页
分页是WEB项目中比不可少的一个功能,数据量大的时候不能全部展示必然要用到分页技术。相信大家对hibernate中的分页都不陌生:
Java代码 
public Query setMaxResults(int maxResults);  
public Query setFirstResult(int firstResult); 
Java代码 
public Query setMaxResults(int maxResults); 
public Query setFirstResult(int firstResult); 

只要调用了这两个方法并设置好参数,hibernate自动分页完全屏蔽了底层分页技术,这也是众多开发者喜欢hibernate的原因之一。
项目开发中遇到一个奇怪的问题。数据库采用的是SQL Server 2005,也设置了上面两个参数,可是每次发送到数据库端的SQL语句都是select top ....语句。即便是查询第10w条,也只有一个select top 语句,不免引起对hibernate实现sql server分页的怀疑。hibernate针对不同数据库实现的分页方法封装在对应数据库的方言里,通过getLimitString方法转化成对应数据库的分页算法
以常见的Mysql数据库的方言mysqlDialect为例:
Java代码 
public String getLimitString(String sql, boolean hasOffset) {  
        return new StringBuffer( sql.length() + 20 )  
                .append( sql )  
                .append( hasOffset ? " limit ?, ?" : " limit ?" )  
                .toString();  
    } 
Java代码 
public String getLimitString(String sql, boolean hasOffset) { 
        return new StringBuffer( sql.length() + 20 ) 
                .append( sql ) 
                .append( hasOffset ? " limit ?, ?" : " limit ?" ) 
                .toString(); 
    } 

采用了大家熟悉的的limit进行分页。
数据库的方言oracle9iDialect:
Java代码 
StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );  
        if (hasOffset) {  
            pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");  
        }  
        else {  
            pagingSelect.append("select * from ( ");  
        }  
        pagingSelect.append(sql);  
        if (hasOffset) {  
            pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");  
        }  
        else {  
            pagingSelect.append(" ) where rownum <= ?");  
        } 
Java代码 
StringBuffer pagingSelect = new StringBuffer( sql.length()+100 ); 
        if (hasOffset) { 
            pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( "); 
        } 
        else { 
            pagingSelect.append("select * from ( "); 
        } 
        pagingSelect.append(sql); 
        if (hasOffset) { 
            pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?"); 
        } 
        else { 
            pagingSelect.append(" ) where rownum <= ?"); 
        } 

利用Oracle的rownum 结合三层嵌套查询完成分页。这个三层是Oracle最经典高效的分页算法。
可是针对Sql Server的方言SQLServerDialect:
Java代码 
public String getLimitString(String querySelect, int offset, int limit) {  
        if ( offset > 0 ) {  
            throw new UnsupportedOperationException( "query result offset is not supported" );  
        }  
        return new StringBuffer( querySelect.length() + 8 )  
                .append( querySelect )  
                .insert( getAfterSelectInsertPoint( querySelect ), " top " + limit )  
                .toString();  
    } 
Java代码 
public String getLimitString(String querySelect, int offset, int limit) { 
        if ( offset > 0 ) { 
            throw new UnsupportedOperationException( "query result offset is not supported" ); 
        } 
        return new StringBuffer( querySelect.length() + 8 ) 
                .append( querySelect ) 
                .insert( getAfterSelectInsertPoint( querySelect ), " top " + limit ) 
                .toString(); 
    } 

揉揉眼睛、再揉揉,没错,只出现了一个top语句。这就意味着如果查询第10w页的数据,需要把前10w页数据全部提取出来。hibernate针对sql server的分页是伪分页,所以随着数据量日益增加用户抱怨系统速度慢,程序员抱怨hibernate性能低,dba抱怨开发人员sql功底太浅。
不知道hibernate开发组,出于什么目前或情况没有真正提供sql server的分页技术,那我们自己来实现。
方言类:
Java代码 
public class SQLServer2005Dialect extends SQLServerDialect {  
 
     
 
    private ThreadLocal<Boolean> supportsVariableLimit = new ThreadLocal<Boolean>();  
    public SQLServer2005Dialect() {  
        reGISterFunction("bitand", new BitAndFunction());  
        registerFunction("bitxor", new BitXorFunction());  
        registerFunction("bitor", new BitOrFunction());  
        setSupportsVariableLimit(false);  
    }  
 
     
 
    private void setSupportsVariableLimit(boolean first) {  
        this.supportsVariableLimit.set(Boolean.valueOf(first));  
    }  
 
     
    protected static int getSqlAfterSelectInsertPoint(String sql) {  
        int selectIndex = sql.toLowerCase().indexOf("select");  
 
        int selectDistinctIndex = sql.toLowerCase().indexOf("select distinct");  
 
        return selectIndex + ((selectDistinctIndex == selectIndex) ? 15 : 6);  
    }  
 
    public boolean supportsLimitOffset() {  
        return true;  
    }  
 
     
    public boolean supportsVariableLimit() {  
        return ((Boolean) this.supportsVariableLimit.get()).booleanValue();  
    }  
 
    public boolean useMaxForLimit() {  
        return true;  
    }  
     
    public String getLimitString(String query, int offset, int limit) {  
        setSupportsVariableLimit(offset > 0);  
 
        if (offset == 0) {  
            return new StringBuffer(query.length() + 8).append(query).insert(  
                    getSqlAfterSelectInsertPoint(query), " top " + limit)  
                    .toString();  
        }  
 
        return getLimitString(query, offset > 0);  
    }  
      
    public String getLimitString(String sql, boolean hasOffset) {  
        int orderByIndex = sql.toLowerCase().lastIndexOf("order by");  
 
        if (orderByIndex <= 0) {  
            throw new UnsupportedOperationException(  
                    "must specify 'order by' statement to support limit operation with offset in sql server 2005");  
        }  
 
        String sqlOrderBy = sql.substring(orderByIndex + 8);  
 
        String sqlRemoveOrderBy = sql.substring(0, orderByIndex);  
 
        int insertPoint = getSqlAfterSelectInsertPoint(sql);  
        return new StringBuffer(sql.length() + 100)  
                .append("with tempPagination as(")  
                .append(sqlRemoveOrderBy)  
                .insert(  
                        insertPoint + 23,  
                        " ROW_NUMBER() OVER(ORDER BY " + sqlOrderBy  
                                + ") as RowNumber,")  
                .append(  
                        ") select * from tempPagination where RowNumber>?  and RowNumber<=?")  
                .toString();  
    }  

Java代码 
public class SQLServer2005Dialect extends SQLServerDialect { 
 
     
 
    private ThreadLocal<Boolean> supportsVariableLimit = new ThreadLocal<Boolean>(); 
    public SQLServer2005Dialect() { 
        registerFunction("bitand", new BitAndFunction()); 
        registerFunction("bitxor", new BitXorFunction()); 
        registerFunction("bitor", new BitOrFunction()); 
        setSupportsVariableLimit(false); 
    } 
 
     
 
    private void setSupportsVariableLimit(boolean first) { 
        this.supportsVariableLimit.set(Boolean.valueOf(first)); 
    } 
 
     
    protected static int getSqlAfterSelectInsertPoint(String sql) { 
        int selectIndex = sql.toLowerCase().indexOf("select"); 
 
        int selectDistinctIndex = sql.toLowerCase().indexOf("select distinct"); 
 
        return selectIndex + ((selectDistinctIndex == selectIndex) ? 15 : 6); 
    } 
 
    public boolean supportsLimitOffset() { 
        return true; 
    } 
 
     
    public boolean supportsVariableLimit() { 
        return ((Boolean) this.supportsVariableLimit.get()).booleanValue(); 
    } 
 
    public boolean useMaxForLimit() { 
        return true; 
    } 
     
    public String getLimitString(String query, int offset, int limit) { 
        setSupportsVariableLimit(offset > 0); 
 
        if (offset == 0) { 
            return new StringBuffer(query.length() + 8).append(query).insert( 
                    getSqlAfterSelectInsertPoint(query), " top " + limit) 
                    .toString(); 
        } 
 
        return getLimitString(query, offset > 0); 
    } 
     
    public String getLimitString(String sql, boolean hasOffset) { 
        int orderByIndex = sql.toLowerCase().lastIndexOf("order by"); 
 
        if (orderByIndex <= 0) { 
            throw new UnsupportedOperationException( 
                    "must specify 'order by' statement to support limit operation with offset in sql server 2005"); 
        } 
 
        String sqlOrderBy = sql.substring(orderByIndex + 8); 
 
        String sqlRemoveOrderBy = sql.substring(0, orderByIndex); 
 
        int insertPoint = getSqlAfterSelectInsertPoint(sql); 
        return new StringBuffer(sql.length() + 100) 
                .append("with tempPagination as(") 
                .append(sqlRemoveOrderBy) 
                .insert( 
                        insertPoint + 23, 
                        " ROW_NUMBER() OVER(ORDER BY " + sqlOrderBy 
                                + ") as RowNumber,") 
                .append( 
                        ") select * from tempPagination where RowNumber>?  and RowNumber<=?") 
                .toString(); 
    } 

函数:
Java代码 
public class BitAndFunction implements SQLFunction {  
    public Type getReturnType(Type type, Mapping mapping) {  
        return Hibernate.INTEGER;  
    }  
 
    public boolean hasArguments() {  
        return true;  
    }  
 
    public boolean hasParenthesesIfNoArguments() {  
        return true;  
    }  
 
    public String render(List args, SessionFactoryImplementor factory)  
            throws QueryException {  
        if (args.size() != 2) {  
            throw new IllegalArgumentException(  
                    "BitAndFunction requires 2 arguments!");  
        }  
        return args.get(0).toString() + " & " + args.get(1).toString();  
    }  

Java代码 
public class BitAndFunction implements SQLFunction { 
    public Type getReturnType(Type type, Mapping mapping) { 
        return Hibernate.INTEGER; 
    } 
 
    public boolean hasArguments() { 
        return true; 
    } 
 
    public boolean hasParenthesesIfNoArguments() { 
        return true; 
    } 
 
    public String render(List args, SessionFactoryImplementor factory) 
            throws QueryException { 
        if (args.size() != 2) { 
            throw new IllegalArgumentException( 
                    "BitAndFunction requires 2 arguments!"); 
        } 
        return args.get(0).toString() + " & " + args.get(1).toString(); 
    } 

 
Java代码 
public class BitOrFunction implements SQLFunction {  
    public Type getReturnType(Type type, Mapping mapping) {  
        return Hibernate.INTEGER;  
    }  
    public boolean hasArguments() {  
        return true;  
    }  
    public boolean hasParenthesesIfNoArguments() {  
        return true;  
    }  
    public String render(List args, SessionFactoryImplementor factory)  
            throws QueryException {  
        if (args.size() != 2) {  
            throw new IllegalArgumentException(  
                    "BitOrFunction requires 2 arguments!");  
        }  
        return args.get(0).toString() + " | " + args.get(1).toString();  
    }  

Java代码 
public class BitOrFunction implements SQLFunction { 
    public Type getReturnType(Type type, Mapping mapping) { 
        return Hibernate.INTEGER; 
    } 
    public boolean hasArguments() { 
        return true; 
    } 
    public boolean hasParenthesesIfNoArguments() { 
        return true; 
    } 
    public String render(List args, SessionFactoryImplementor factory) 
            throws QueryException { 
        if (args.size() != 2) { 
            throw new IllegalArgumentException( 
                    "BitOrFunction requires 2 arguments!"); 
        } 
        return args.get(0).toString() + " | " + args.get(1).toString(); 
    } 

 
Java代码 
public Type getReturnType(Type type, Mapping mapping) {  
        return Hibernate.INTEGER;  
    }  
    public boolean hasArguments() {  
        return true;  
    }  
    public boolean hasParenthesesIfNoArguments() {  
        return true;  
    }  
    public String render(List args, SessionFactoryImplementor factory)  
            throws QueryException {  
        if (args.size() != 2) {  
            throw new IllegalArgumentException(  
                    "BitXorFunction requires 2 arguments!");  
        }  
        return args.get(0).toString() + " ^ " + args.get(1).toString();  
    } 


到此,关于“sqlserver2005的分页优化”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

您可能感兴趣的文档:

--结束END--

本文标题: sqlserver2005的分页优化

本文链接: https://www.lsjlt.com/news/60671.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • sqlserver2005的分页优化
    这篇文章主要介绍“sqlserver2005的分页优化”,在日常操作中,相信很多人在sqlserver2005的分页优化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”sqls...
    99+
    2024-04-02
  • 如何进行SQL优化中的limit分页优化
    如何进行SQL优化中的limit分页优化,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。示例 表aaaaa中共有2375690数据。优化前的S...
    99+
    2024-04-02
  • 分析SQL优化的limit分页延迟关联
    这篇文章主要介绍“分析SQL优化的limit分页延迟关联”,在日常操作中,相信很多人在分析SQL优化的limit分页延迟关联问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”分析...
    99+
    2024-04-02
  • MySQL分页Limit的优化过程实战
    前言 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能。 SELECT * FROM table LIMIT [o...
    99+
    2024-04-02
  • sql分页查询如何优化
    优化 SQL 分页查询的方法有很多,以下是一些常见的优化策略:1. 使用索引:为要查询的列创建合适的索引,可以大大提高查询速度。尤其...
    99+
    2023-09-20
    sql
  • mysql分页查询如何优化
    这篇文章主要介绍了mysql分页查询如何优化的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇mysql分页查询如何优化文章都会有所收获,下面我们一起来看看吧。 ...
    99+
    2024-04-02
  • jquery如何优化分页操作
    这篇文章主要介绍jquery如何优化分页操作,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!创建数据库语句CREATE TABLE `news` ( &n...
    99+
    2024-04-02
  • 如何进行limit分页优化
    这篇文章给大家介绍如何进行limit分页优化,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 看一个案例 点击(此处)折叠或打开 mysql> ...
    99+
    2024-04-02
  • MySQL查询中分页的思路和优化
    这篇文章主要介绍“MySQL查询中分页的思路和优化”,在日常操作中,相信很多人在MySQL查询中分页的思路和优化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL查询中...
    99+
    2024-04-02
  • SQL优化limit分页的方法是什么
    本篇内容介绍了“SQL优化limit分页的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!&nbs...
    99+
    2024-04-02
  • mysql limit分页性能如何优化
    MySQL的LIMIT子句用于限制查询结果集的数量。在使用LIMIT进行分页时,可以通过一些优化技巧提高性能。 以下是一些优化LIM...
    99+
    2024-04-09
    mysql
  • PHP数组分页的性能优化策略
    提高 php 数组分页性能的策略包括:避免使用 foreach 循环,使用 array_slice() 函数。使用 array_chunk() 函数将数组划分为更小的块。通过数据库分页、...
    99+
    2024-05-02
    php 数组分页 mysql
  • MySQL中怎么优化查询分页
    这期内容当中小编将会给大家带来有关MySQL中怎么优化查询分页,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。  MySQL查询分页怎么优化  如果你的数据量有几十万条,用...
    99+
    2024-04-02
  • MySQL中怎么优化分页查询
    今天就跟大家聊聊有关MySQL中怎么优化分页查询,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。 分页查询方法:在MySQL中,分页查询一般...
    99+
    2024-04-02
  • 如何在mysql中优化LIMIT分页
    这篇文章将为大家详细讲解有关如何在mysql中优化LIMIT分页,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1、优化方法尽可能的使用覆盖索引扫描,而不是查询所有的列。然后根据需要做一次关联...
    99+
    2023-06-15
  • Vue列表页渲染优化的示例分析
    小编给大家分享一下Vue列表页渲染优化的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!想法初始化时,vue会对data做...
    99+
    2024-04-02
  • MyBatis分页查询优化的方法是什么
    MyBatis分页查询的优化方法主要包括以下几点: 使用分页插件:MyBatis提供了一些分页插件,如MyBatis-PageH...
    99+
    2024-03-04
    MyBatis
  • mongodb分页查询优化的方法有哪些
    有以下几种方法可以优化MongoDB的分页查询:1. 使用索引:为分页查询的字段创建索引,这可以大大提高查询性能。在分页查询中,常用...
    99+
    2023-08-23
    mongodb
  • MySQL Limit性能优化及分页数据性能优化详解
    MySQL Limit可以分段查询数据库数据,主要应用在分页上。虽然现在写的网站数据都是千条级别,一些小的的优化起的作用不大,但是开发就要做到极致,追求完美性能。下面记录一些limit性能优化方法。 Lim...
    99+
    2024-04-02
  • oracle分页查询优化的方法是什么
    Oracle数据库提供了几种方法来优化分页查询:1. 使用ROWNUM:ROWNUM是一个伪列,表示返回结果集中的行数。可以在查询中...
    99+
    2023-09-20
    oracle
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作