连接数据库次数问题,急啊!
小弟做个网站,首页显示的时候:
从数据库的一个表里读取,然后分类显示(比较多,按30类),每个类别都显示出前几条内容。(现暂定8条)
现在的问题是:
1、如果说一次从数据库里读取出来再进行筛选的话,我必须判断每个类别不超过8条,这样可以实现,但必须把表里的数据全读出来,如果几万条呢,可我只显示那几十条,太影响性能了。
2、所以我考虑不一次读取,但根据我掌握的知识就要从数据库查询30次,光个首页就要打开这么多次连接,是不是也太影响性能了?
3、我该怎么办?个位高手、大侠有没有好的办法,可不要笑小弟无知啊!
[解决办法]
SqlServer通用存储过程(1)-千万级数据库高速分页显示
/*
经测试,在 14483461 条记录中查询第 100000 页,每页 10 条记录按升序和降序第一次时间均为 0.47 秒,第二次时间均为 0.43 秒,测试语法如下:
exec GetRecordFromPage news,newsid,10,100000
news 为 表名, newsid 为关键字段, 使用时请先对 newsid 建立索引。
*/
/*
函数名称: GetRecordFromPage
函数功能: 获取指定页的数据
参数说明: @tblName 包含数据的表名
@fldName 关键字段名
@PageSize 每页记录数
@PageIndex 要获取的页码
@OrderType 排序类型, 0 - 升序, 1 - 降序
@strWhere 查询条件 (注意: 不要加 where)
*/
CREATE PROCEDURE GetRecordFromPage
@tblName varchar(255), -- 表名
@fldName varchar(255), -- 字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(2000) = ' ' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL varchar(6000) -- 主语句
declare @strTmp varchar(1000) -- 临时变量
declare @strOrder varchar(500) -- 排序类型
if @OrderType != 0
begin
set @strTmp = " <(select min "
set @strOrder = " order by [ " + @fldName + "] desc "
end
else
begin
set @strTmp = "> (select max "
set @strOrder = " order by [ " + @fldName + "] asc "
end
set @strSQL = "select top " + str(@PageSize) + " * from [ "
+ @tblName + "] where [ " + @fldName + "] " + @strTmp + "([ "
+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " [ "
+ @fldName + "] from [ " + @tblName + "] " + @strOrder + ") as tblTmp) "
+ @strOrder
if @strWhere != ' '
set @strSQL = "select top " + str(@PageSize) + " * from [ "
+ @tblName + "] where [ " + @fldName + "] " + @strTmp + "([ "
+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " [ "
+ @fldName + "] from [ " + @tblName + "] where " + @strWhere + " "
+ @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder
if @PageIndex = 1
begin
set @strTmp = " "
if @strWhere != ' '
set @strTmp = " where ( " + @strWhere + ") "
set @strSQL = "select top " + str(@PageSize) + " * from [ "
+ @tblName + "] " + @strTmp + " " + @strOrder
end
exec (@strSQL)
GO
-----------
另一个版本
/*
函数名称: GetRecordFromPage
函数功能: 获取指定页的数据
参数说明: @tblName 包含数据的表名
@fldName 关键字段名
@PageSize 每页记录数
@PageIndex 要获取的页码
@IsCount 是否要取得记录数
@OrderType 排序类型, 0 - 升序, 1 - 降序
@strWhere 查询条件 (注意: 不要加 where)
*/
CREATE PROCEDURE pGO_GetRecordFromPage
@tblName varchar(255), -- 表名
@fldName varchar(255), -- 字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@IsCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1000) = ' ' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL varchar(6000) -- 主语句
declare @strTmp varchar(500) -- 临时变量
declare @strOrder varchar(400) -- 排序类型
-- 如果是查询记录总数,直接使用Count(0)函数
if @IsCount != 0
begin
if @strWhere != ' '
set @strSQL = 'select count(*) as Total from [ ' + @tblName + '] where ' + @strWhere
else
set @strSQL = 'select count(*) as Total from [ ' + @tblName + '] '
end
--如果是想查询记录,则
else
begin
if @PageIndex = 1
begin
set @strTmp = ' '
if @strWhere != ' '
set @strTmp = ' where ' + @strWhere
set @strSQL = 'select top ' + str(@PageSize) + ' * from [ '
+ @tblName + '] ' + @strTmp + ' ' + @strOrder
end
else
begin
--如果是降序查询……
if @OrderType != 0
begin
set @strTmp = ' <(select min '
set @strOrder = ' order by [ ' + @fldName + '] desc '
end
--如果是升序查询……
else
begin
set @strTmp = '> (select max '
set @strOrder = ' order by [ ' + @fldName + '] asc '
end
if @strWhere != ' '
set @strSQL = 'select top ' + str(@PageSize) + ' * from [ '
+ @tblName + '] where [ ' + @fldName + '] ' + @strTmp + '([ '
+ @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' [ '
+ @fldName + '] from [ ' + @tblName + '] where ' + @strWhere + ' '
+ @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
else
set @strSQL = 'select top ' + str(@PageSize) + ' * from [ '
+ @tblName + '] where [ ' + @fldName + '] ' + @strTmp + '([ '
+ @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' [ '
+ @fldName + '] from [ ' + @tblName + '] ' + @strOrder + ') as tblTmp) '
+ @strOrder
end
end
exec (@strSQL)
GO
-----
可以实现多表查询。
-- =============================================
-- 数据分页的存储过程
-- 记录号在 TempIDKey_Num 字段中
-- 调用的例子: 表示 从结果中第3行开始的5条记录。
-- T-SQL:EXECUTE proTest N 'select top 100 percent * from orders ', 3,5
-- ASP.NET(C#):
-- <%@ Page Language= "C# " %>
-- <%@ Import Namespace= "System.Data " %>
-- <%@ Import Namespace= "System.Data.SqlClient " %>
-- <Script Runat= "Server ">
-- void Page_Load( Object s, EventArgs e )
-- {
-- SqlConnection myConnection;
-- SqlCommand myCommand;
-- myConnection = new SqlConnection( "Server=(local);uid=sa;pwd=11;Database=Northwind " );
-- myCommand = new SqlCommand( "proTest ", myConnection );
-- myCommand.CommandType = CommandType.StoredProcedure;
-- myCommand.Parameters.Add( "@strSql ", "Select top 30 * from orders ");
-- myCommand.Parameters.Add( "@startRow ",10);
-- myCommand.Parameters.Add( "@maxRows ",15);
-- myConnection.Open();
-- myDataGrid.DataSource = myCommand.ExecuteReader();
-- myDataGrid.DataBind();
-- myConnection.Close();
-- }
-- </Script>
-- <html> <head> <title> DataGrid </title> </head> <body>
-- <form Runat= "Server ">
-- <asp:DataGrid id= "myDataGrid " Runat= "Server "/>
-- </form>
-- </body> </html>
-- =============================================
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = N 'proTest '
AND type = 'P ')
DROP PROCEDURE proTest
GO
CREATE PROCEDURE proTest
@strSql as nvarchar(2000) = null, --要查询语句如 Select top 30 * from orders
@startRow as int = null, --从其开始的从零开始的记录号
@maxRows as int = null --要检索的最大记录数
AS
DECLARE @stopRow as int
set @stopRow = @startRow + @maxRows
set @strSql = N ' Select top ' + CAST(@StopRow as nvarchar(9)) + '*, IDENTITY(int,1,1) AS TempIDKey_Num '
+ ' INTO #New_Table '
+ ' FROM( ' + @strSql + ') A '
+ ' Select * From #New_Table Where TempIDKey_Num> = ' + CAST(@StartRow as nvarchar(9))
+ ' DROP TABLE #New_Table '
execute sp_executesql @strSql
GO
[解决办法]
你用DataSet取啊,SQL用分号分开,或者用存储过程啊
[解决办法]
数据库连接多就该转化成静态页,只要实时要求不是太高,这样做最好了
[解决办法]
同一个表,分类查询,每类区8条。。一个sql语句就搞定了啊,,
分组、排序,返回一个结果集。 下例取出每个分类的前5条记录,forumid为分类代码
select subject,postid from forums_posts a where postid in (select top 5 postid from forums_posts where forumid= a.forumid order by postdate desc) order by forumid