热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

C#拼接SQL语句用ROW_NUMBER实现的高效分页排序

C#拼接SQL语句,SQLServer2005+,多行多列大数据量情况下,使用ROW_NUMBER实现的高效分页排序
如果项目中要用到数据库,铁定要用到分页排序。之前在做数据库查询优化的时候,通宵写了以下代码,来拼接分页排序的SQL语句

代码如下:

///
/// 单表(视图)获取分页SQL语句
///

/// 表名或视图名
/// 唯一键
/// 获取的字段
/// 查询条件(不包含WHERE)
/// 排序规则(不包含ORDER BY)
/// 页大小
/// 页码(从1开始)
/// 分页SQL语句
public static string GetPagingSQL(
string tableName,
string key,
string fields,
string condition,
string collatingSequence,
int pageSize,
int pageIndex)
{
string whereClause = string.Empty;
if (!string.IsNullOrEmpty(condition))
{
whereClause = string.Format("WHERE {0}", condition);
}

if (string.IsNullOrEmpty(collatingSequence))
{
collatingSequence = string.Format("{0} ASC", key);
}

StringBuilder sbSql = new StringBuilder();

sbSql.AppendFormat("SELECT {0} ", PrependTableName(tableName, fields, ','));
sbSql.AppendFormat("FROM ( SELECT TOP {0} ", pageSize * pageIndex);
sbSql.AppendFormat(" [_RowNum_] = ROW_NUMBER() OVER ( ORDER BY {0} ), ", collatingSequence);
sbSql.AppendFormat(" {0} ", key);
sbSql.AppendFormat(" FROM {0} ", tableName);
sbSql.AppendFormat(" {0} ", whereClause);
sbSql.AppendFormat(" ) AS [_TempTable_] ");
sbSql.AppendFormat(" INNER JOIN {0} ON [_TempTable_].{1} = {0}.{1} ", tableName, key);
sbSql.AppendFormat("WHERE [_RowNum_] > {0} ", pageSize * (pageIndex - 1));
sbSql.AppendFormat("ORDER BY [_TempTable_].[_RowNum_] ASC ");

return sbSql.ToString();
}

///
/// 给字段添加表名前缀
///

/// 表名
/// 字段
/// 标识字段间的分隔符
///
public static string PrependTableName(string tableName, string fields, char separator)
{
StringBuilder sbFields = new StringBuilder();

string[] fieldArr = fields.Trim(separator).Split(separator);
foreach (string str in fieldArr)
{
sbFields.AppendFormat("{0}.{1}{2}", tableName, str.Trim(), separator);
}

return sbFields.ToString().TrimEnd(separator);
}

假设有如下产品表:
代码如下:

CREATE TABLE [dbo].[Tbl_Product]
(
[ID] [int] IDENTITY(1, 1)
NOT NULL ,
[ProductId] [varchar](50) NOT NULL ,
[ProductName] [nvarchar](50) NOT NULL ,
[IsDeleted] [int] NOT NULL
CONSTRAINT [DF_Tbl_Product_IsDeleted] DEFAULT ( (0) ) ,
CONSTRAINT [PK_Tbl_Product] PRIMARY KEY CLUSTERED ( [ProductId] ASC )
WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY]
)
ON [PRIMARY]

Tbl_Product->ID(序号,非空,自增)
Tbl_Product->ProductId(产品Id,主键)
Tbl_Product->ProductName(产品名称,非空)
Tbl_Product->IsDeleted(虚拟删除标记,非空)
调用BasicFunction.GetPagingSQL("Tbl_Product", "ID", "ID,ProductId,ProductName", "IsDeleted=0", "ProductName ASC, ID DESC", 5, 5),BasicFunction为分页排序方法所在的静态类,生成的分页排序SQL语句如下(已手动调整了格式):
代码如下:

SELECT Tbl_Product.ID ,
Tbl_Product.ProductId ,
Tbl_Product.ProductName
FROM ( SELECT TOP 25
[_RowNum_] = ROW_NUMBER() OVER ( ORDER BY ProductName ASC, ID DESC ) ,
ID
FROM Tbl_Product
WHERE IsDeleted = 0
) AS [_TempTable_]
INNER JOIN Tbl_Product ON [_TempTable_].ID = Tbl_Product.ID
WHERE [_RowNum_] > 20
ORDER BY [_TempTable_].[_RowNum_] ASC

查询的字段列表,去掉了不关心的字段(这里为IsDeleted,因为条件里面IsDeleted=0,查出来的产品都是没被删除的);
排序依据,在调用该方法时,应尽量确保排序的依据可以唯一确定记录在结果集中的位置(这里添加了辅助排序依据,ID DESC,如果产品重名,添加的晚的排在前面);
性能优化的一点儿建议:如果字段的值是计算出来的,如:总价=单价*数量,而此时需要总价大于多少的记录,还得拿总价递增或者递减排序,如果不要临时表,数据量大的时候,就等着买新电脑吧!你问我为什么要买新电脑,哦,因为你会把现在的电脑砸掉!O(∩_∩)O~
另外一点儿建议,使用ROW_NUMBER时,切记一定要和“TOP n”一起使用,n等于int.MaxValue都比不加“TOP n”时要快。
最后,拜托哪位好心人士给测试下性能,拜托了,本人数据库菜鸟,不太懂得数据库的性能测试。

我只知道我对我写的分页排序还是很有信心的,(*^__^*) 嘻嘻!

首发:博客园->剑过不留痕
推荐阅读
  • 本文介绍如何通过创建数据库触发器来限制Oracle数据库中特定用户的登录IP地址,以增强系统的安全性。示例代码展示了如何阻止非授权IP地址的登录尝试。 ... [详细]
  • 本文探讨了在SharePoint环境中使用BDC(Business Data Catalog)时遇到的问题及其解决策略,包括XML文件导入SSP后的不可见性问题以及与远程SQL Server 2005连接的难题。 ... [详细]
  • SQL查询与事务管理:深入解析
    本文详细介绍了SQL查询的基本结构和高级特性,包括选择、分组查询以及权限控制等内容,并探讨了事务管理中的并发控制策略,旨在为数据库管理员和开发人员提供实用指导。 ... [详细]
  • PHP 图形函数中实现汉字显示的方法
    本文详细介绍了如何在 PHP 的图形函数中正确显示汉字,包括具体的步骤和注意事项,适合初学者和有一定基础的开发者阅读。 ... [详细]
  • 2023年1月28日网络安全热点
    涵盖最新的网络安全动态,包括OpenSSH和WordPress的安全更新、VirtualBox提权漏洞、以及谷歌推出的新证书验证机制等内容。 ... [详细]
  • 本文由公众号【数智物语】(ID: decision_engine)发布,关注获取更多干货。文章探讨了从数据收集到清洗、建模及可视化的全过程,介绍了41款实用工具,旨在帮助数据科学家和分析师提升工作效率。 ... [详细]
  • 本文深入探讨了MySQL中的高级特性,包括索引机制、锁的使用及管理、以及如何利用慢查询日志优化性能。适合有一定MySQL基础的读者进一步提升技能。 ... [详细]
  • 将XML数据迁移至Oracle Autonomous Data Warehouse (ADW)
    随着Oracle ADW的推出,数据迁移至ADW成为业界关注的焦点。特别是XML和JSON这类结构化数据的迁移需求日益增长。本文将通过一个实际案例,探讨如何高效地将XML数据迁移至ADW。 ... [详细]
  • 在使用mybatis进行mapper.xml测试的时候发生必须为元素类型“mapper”声明属性“namespace”的错误项目目录结构UserMapper和UserMappe ... [详细]
  • Windows环境下Oracle数据库迁移实践
    本文详细记录了一次在Windows操作系统下将Oracle数据库的控制文件、数据文件及在线日志文件迁移至外部存储的过程,旨在为后续的集群环境部署做好准备。 ... [详细]
  • 面对众多的数据分析工具,如何选择最适合自己的那一个?对于初学者而言,了解并掌握几种核心工具是快速入门的关键。本文将从数据处理的不同阶段出发,推荐三种广泛使用的数据分析工具。 ... [详细]
  • Java连接MySQL数据库的方法及测试示例
    本文详细介绍了如何安装MySQL数据库,并通过Java编程语言实现与MySQL数据库的连接,包括环境搭建、数据库创建以及简单的查询操作。 ... [详细]
  • 本文详细介绍了如何使用SQL*Plus连接Oracle数据库以及使用MySQL客户端连接MySQL数据库的方法,包括基本命令和具体操作步骤。 ... [详细]
  • 本文探讨了如何使用Scrapy框架构建高效的数据采集系统,以及如何通过异步处理技术提升数据存储的效率。同时,文章还介绍了针对不同网站采用的不同采集策略。 ... [详细]
  • 本文探讨了如何在SQL Server Reporting Services (SSRS)中利用TOP N功能来筛选和展示数据集中的前N条记录。通过正确的配置图表属性中的筛选器设置,可以轻松实现这一目标。 ... [详细]
author-avatar
自由战狼2012
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有