分頁解決方案 之 分頁演算法——Pager_SQL的思路和使用方法
分頁演算法(也就是分頁讀取資料的時候使用的select 語句)面臨兩大難題:一個是不同的資料庫使用的分頁演算法是不一樣的(比如SQL Server 2000可以使用Max、表變數、顛倒Top,SQL Server 2005可以使用Row_Number,MySql可以使用limit ,Orcale可以使用ROWNUM等);另一個是,不同的分頁需求,可以採用的分頁演算法也是不一樣的(比如單欄位排序和多欄位排序)。那麼我們應該如何來選擇呢?
好多人都想找到一種即通用,效率又高的分頁演算法,那麼能不能找到呢?我是找了很久都沒有找到,看了許多人寫得文章,我也沒有發現(請不要和我說那個什麼表變數的)。既然找不到,那就要做多手準備了。
我的想法就是準備多種分頁演算法的“模板”,然後根據資料庫的種類,根據分頁需求來選擇到底是用哪一種分頁演算法。就是說使用哪一種是不固定的,依據條件而定。那麼如何來實現呢?我做了一個類庫來做這個事情,請看下面的圖示:
Pager_SQL原來是QuickPager分頁控制元件的一部分,現在獨立出來可以單獨使用。
Pager_SQL就好像一個加工廠,給他輸入“原料”(表名、欄位名、排序欄位等),然後再選擇“加工方式”(選擇分頁演算法),最後我們就可以得到所需的“產品”(分頁用的select 語句)了。
因為不管是什麼資料庫(只要是關係型資料庫),那麼就會有表、欄位、檢視,要分頁就要有排序欄位等,所以呢這些原料都是固定的,變化的只是分頁用的SQL語句,這個Pager_SQL就是“生產”各種SQL語句的工廠。這樣不同的分頁演算法既可以適應不同的資料庫,也可以使用不同的分頁需求。
Pager_SQL的原理很簡單,就是拼接字串(也就是拼接SQL語句),然後通過資料訪問函式庫(或者其他的help等)提交給資料庫執行。採用了基類的方式,所以如果需要增加分頁演算法的話,那麼只要繼承這個基類寫一個子類,如果有不同的地方,覆蓋一下就可以了。下面是類圖:
說到這裡,您可能會有兩個疑問:1、拼接字串的效率是不是會很慢?2、SQL語句和儲存過程相比是不是很慢?兩個“慢”加起來,是不是變成了“巨慢”。一開始我也是比較擔心,但是用了五年多,也用100萬條記錄做過測試,效率還是很理想的。這兩天我又詳細的測試了一下,在測試的過程中也發現了不少細節問題,以前忽略的地方,由於測試的比較亂,所以我想整理一下然後再寫出來。
使用方法:
//例項化
JYK.Controls.Pager.QuickPagerSQL PagerSQL = new QuickPagerSQL();
protected void Page_Load(object sender, EventArgs e)
{
//設定屬性
PagerSQL.TableName = "News_NewsInfo"; //表名或者檢視名稱
PagerSQL.TableShowColumns = "*"; //需要顯示的欄位
PagerSQL.TableIDColumn = "NewsID"; //主鍵名稱,不支援複合主鍵
PagerSQL.TableOrderByColumns = "NewsID"; //排序欄位,根據分頁演算法而定,可以支援多個排序欄位
PagerSQL.TableQuery = ""; //查詢條件
PagerSQL.PageSize = 4; //一頁顯示的記錄數
PagerSQL.PageCount = 100;
PagerSQL.ComputePageCount(100,4);
}
測試拼接字串的效率#region 測試拼接字串的效率
protected void Btn_Satart_Click(object sender, EventArgs e)
{
//測試拼接字串的效率
//選擇一個分頁演算法
PagerSQL.SetPagerSQLKind = PagerSQLKind.MaxMin;
//生成分頁演算法
PagerSQL.CreateSQL();
Response.Write( "檢查生成的SQL語句:" + PagerSQL.GetSQLByPageIndex(2) + "<BR>"); //測試用,顯示第二頁的分頁演算法
//開始計時,記錄迴圈一萬次的時間
int a = Environment.TickCount;
for (int i = 0; i < 10000; i++)
{
PagerSQL.CreateSQL();
}
int b = Environment.TickCount - a;
Response.Write("迴圈10000次用時:");
Response.Write(b + "毫秒<BR>");
}
#endregion
原始碼下載:http://www.cnblogs.com/jyk/archive/2008/07/29/1255891.html
ps:下一篇裡我會測試程式裡面拼接字串的時間、SQL Server2000分析、製作執行計劃的時間,SQL語句和儲存過程的對比,exe (@sql)和 exec sp_executesql @sql 的區別。