天天看點

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

      分頁算法(也就是分頁讀取資料的時候使用的select 語句)面臨兩大難題:一個是不同的資料庫使用的分頁算法是不一樣的(比如SQL Server 2000可以使用Max、表變量、颠倒Top,SQL Server 2005可以使用Row_Number,MySql可以使用limit ,Orcale可以使用ROWNUM等);另一個是,不同的分頁需求,可以采用的分頁算法也是不一樣的(比如單字段排序和多字段排序)。那麼我們應該如何來選擇呢?

      好多人都想找到一種即通用,效率又高的分頁算法,那麼能不能找到呢?我是找了很久都沒有找到,看了許多人寫得文章,我也沒有發現(請不要和我說那個什麼表變量的)。既然找不到,那就要做多手準備了。

      我的想法就是準備多種分頁算法的“模闆”,然後根據資料庫的種類,根據分頁需求來選擇到底是用哪一種分頁算法。就是說使用哪一種是不固定的,依據條件而定。那麼如何來實作呢?我做了一個類庫來做這個事情,請看下面的圖示:

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

      Pager_SQL原來是QuickPager分頁控件的一部分,現在獨立出來可以單獨使用。

      Pager_SQL就好像一個加工廠,給他輸入“原料”(表名、字段名、排序字段等),然後再選擇“加工方式”(選擇分頁算法),最後我們就可以得到所需的“産品”(分頁用的select 語句)了。

      因為不管是什麼資料庫(隻要是關系型資料庫),那麼就會有表、字段、視圖,要分頁就要有排序字段等,是以呢這些原料都是固定的,變化的隻是分頁用的SQL語句,這個Pager_SQL就是“生産”各種SQL語句的工廠。這樣不同的分頁算法既可以适應不同的資料庫,也可以使用不同的分頁需求。

      Pager_SQL的原理很簡單,就是拼接字元串(也就是拼接SQL語句),然後通過資料通路函數庫(或者其他的help等)送出給資料庫執行。采用了基類的方式,是以如果需要增加分頁算法的話,那麼隻要繼承這個基類寫一個子類,如果有不同的地方,覆寫一下就可以了。下面是類圖:

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

      說到這裡,您可能會有兩個疑問:1、拼接字元串的效率是不是會很慢?2、SQL語句和儲存過程相比是不是很慢?兩個“慢”加起來,是不是變成了“巨慢”。一開始我也是比較擔心,但是用了五年多,也用100萬條記錄做過測試,效率還是很理想的。這兩天我又詳細的測試了一下,在測試的過程中也發現了不少細節問題,以前忽略的地方,由于測試的比較亂,是以我想整理一下然後再寫出來。

使用方法:

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

//執行個體化

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

JYK.Controls.Pager.QuickPagerSQL PagerSQL = new QuickPagerSQL();

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

protected void Page_Load(object sender, EventArgs e)

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

{

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            //設定屬性

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.TableName = "News_NewsInfo";          //表名或者視圖名稱

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.TableShowColumns = "*";               //需要顯示的字段

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.TableIDColumn = "NewsID";             //主鍵名稱,不支援複合主鍵

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.TableOrderByColumns = "NewsID";       //排序字段,根據分頁算法而定,可以支援多個排序字段

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.TableQuery = "";                      //查詢條件

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.PageSize = 4;                         //一頁顯示的記錄數

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.PageCount = 100;

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.ComputePageCount(100,4);

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

        }

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

        測試拼接字元串的效率#region 測試拼接字元串的效率

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

        protected void Btn_Satart_Click(object sender, EventArgs e)

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            //測試拼接字元串的效率

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            //選擇一個分頁算法

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.SetPagerSQLKind = PagerSQLKind.MaxMin;

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            //生成分頁算法

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            PagerSQL.CreateSQL();

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            Response.Write( "檢查生成的SQL語句:" + PagerSQL.GetSQLByPageIndex(2) + "<BR>");               //測試用,顯示第二頁的分頁算法

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            //開始計時,記錄循環一萬次的時間

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            int a = Environment.TickCount;

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            for (int i = 0; i < 10000; i++)

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

                PagerSQL.CreateSQL();

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            }

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            int b = Environment.TickCount - a;

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            Response.Write("循環10000次用時:");

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

            Response.Write(b + "毫秒<BR>");

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

        #endregion

分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法
分頁解決方案 之 分頁算法——Pager_SQL的思路和使用方法

ps:下一篇裡我會測試程式裡面拼接字元串的時間、SQL Server2000分析、制作執行計劃的時間,SQL語句和儲存過程的對比,exe (@sql)和 exec sp_executesql @sql 的差別。