Pages

Subscribe:

Ads 468x60px

Labels

2015年9月9日 星期三

Visual FoxPro 9中新的數據處理方式

資料來源
Visual FoXPro 9.0與以前的版本相比,在數據引擎上做了很大的改進。從增強的SQL語言到支持新的數據類型和索引都作了增強,本文闡述了這個最新版本作爲一個成熟開發平台的魅力。
  數據引擎的改變主要體現在以下5個方面:
  · 增強的SQL語言:取消了很多硬編碼的限制,增強了子查詢和關聯查詢的支持,支持更複雜的表達式,以及增強了對UNION的支持。
  · 性能方面:加入了一個全新的索引方式,增加了過濾型索引的性能,提高了了TOP n ,MIN()/MAX()以及LIKE這些查詢子句的性能。
  · 命令和函數:對數據操作的更具靈活性,增強對SQL中showplan的支持,增加ICASE()來代替IIF()函數。
  · 新的數據類型:支持VarChar、VarBinary和BLOB等新的數據類型,並提供相應的類型轉換函數:CAST()。增強了現有函數對數據類型的控制和轉換能力
  · 遠程數據:增強了事務控制的能力,遊標機制使得代碼邏輯更加清楚,並且對CursorAdapter作了加強,使開發者只需數行代碼就可以方便地訪問遠程視圖。
  由于提供了與SQLServer強有力的互操作性,Visual FoxPro 9對客戶端/服務器模式做了很大的改進。通過支持新的數據類型,並取消了SQL語言的諸多限制,同一套代碼可同時運行在本地數據引擎和SQL Server這兩種不同的數據源上。 
  以上是大致的描述,下面讓我們深入剖析這些新增功能。
  SQL子查詢的增強
  假如要用一句話來表示SQL子查詢的增強程度,那就是:“太多了”!SQL語句中再沒有了元素數量的硬編碼限制。一個簡單的SELECT語句能包括更多的表、連接、子查詢、嵌套子查詢和聯結。
  SQL語句中的IN子句中再也沒有數量限制。在以前的版本中IN實際被映射到了一個名字INLIST()函數中,但現在這種依靠取消了。這個改變使得IN子句能使用更多的參數來生成非常複雜的SQL語句。與原來版本不同,只要找到相應記錄,Visual FoxPro 9會自動停止計算IN子句中的表達式,這將帶來性能的提高。
  完全無限制?
  IN參數表的元素也不是完全無限的,它的最大數量等于函數SYS(3055)的返回值,而這個函數的返回值與實際可用內存有關,因此假如你的可用內存越大,那麽IN子句支持的元素就越多。無硬編碼的限制並不等于完全無限制。像可用內存以及表達式的複雜性都能決定是否能運行一個非常長而且複雜的語句,你要花很大的功夫才能找出它們在你的機器上的真實極限。
  增強的子查詢功能
  子查詢在SQL語言中是一個很有用的功能。它一般處于WHERE子句中的右邊,充當一個選擇器的作用。在Visual FoxPro 9中,子查詢還可以處于SELECT的參數列表中(稱爲投影)以及FROM子句中(稱爲派生表)。
  當你使用投影時,假如子查詢沒有返回任何記錄,那將返加一個空值(NULL)。投影還答應互相關聯,以後我們會講到這點。
  以下使用投影的SQL語句的一個例子:
  
  SELECT ;
  C.CustomerID, ;
  C.CompanyName, ;
  (SELECT YTD_Sales FROM Sales_02 WHERE ;
  C.CustomerID = Sales_02.CustomerID) AS Y02,;
  (SELECT YTD_Sales FROM Sales_03 WHERE ;
  C.CustomerID = Sales_03.CustomerID) AS Y03,;
  (SELECT YTD_Sales FROM Sales_04 WHERE ;
  C.CustomerID = Sales_04.CustomerID) AS Y04 ;
  FROM Customers C 
  這個SELECT語句返回最後三個會計年度的客戶ID和公司名稱。
  使用投影的限制是子查詢只能查詢一個字段,並且子查詢返回的記錄數不能大于1。
  投影的另一個有價值的使用方法是它可以成爲表達式的一部分,如下所示:
  
  SELECT ;
  C.customerID, ;
  C.companyname, ;
  SUM(D.quantity*D.unitprice) AS CustTotal ,; 
  (SUM(D.quantity*D.unitprice) / ;
  (SELECT SUM((quantity*unitprice)-discount) ;
  FROM OrderDetails D2) ;
  )*100 AS PctTotal ;
  FROM Customers C ;
  INNER JOIN Orders O ;
  ON C.customerID = O.customerID ;
  INNER JOIN OrderDetails D ;
  ON O.orderid = D.orderid ;
  GROUP BY C.customerID, C.companyname, O.orderID ;
  ORDER BY pctTotal DESC
  這個SELECT語句返回客戶ID、公司名稱、銷售額以及銷售額占總銷售額的百分比。
  注重在以上語句中,子查詢充當SELECT列表中的一個複雜表達式,並且它還包含一個聚集函數SUM(),這裏我們可以看到使用它的靈活性。
  子查詢的另一種使用場景即派生表,實際你可以將它看作一個邏輯表。
  考慮以下的例子:
  
  SELECT ;
  C.customerid, ;
  P.prodUCt_count AS p_count;
  FROM Customers C, ;
  (SELECT c2.customerid, ; 
  COUNT(DISTINCT D.productID) AS p_count ;
  FROM Customers C2 ;
  INNER JOIN Orders O ;
  ON C2.customerid = O.customerid ;
  INNER JOIN OrderDetails D ;
  ON O.orderid = D.orderid ;
  GROUP BY c2.customerid) AS P ;
  WHERE C.customerID = p.customerID ;
  AND P.p_count >= ;
  (SELECT (COUNT(*)*.50) FROM Products) ;
  ORDER BY p.product_count DESC
  這個SELECT語句返回客戶ID、所有購買了50%産品的客戶,以及它們所購買的産品數量。
  觀察以上的語句,你可以發現派生表有一個名爲“P”的別名,這與普通字段別名的語法一樣――都必須用AS子句來表達。而且這個子查詢很複雜(在本例中,它關聯了兩個表),這個派生表還可以作爲WHERE子句的一個條件或者將它放在ORDER BY子句中。
  與投影不同,派生表能返回多個字段以及多條記錄,但它不能相互關聯。另外,所有的子查詢都會在主句中的SELECT執行之前運行。
  子查詢還可以充當UPDATE語句中的SET列表。但SET子句只答應使用一個子查詢,並且當SET子句使用子查詢後,那WHERE子句中就不答應再使用子查詢了。
  更好的關聯支持
  新版本中的UPDATE語句和DELETE語句支持關聯。這樣,一條語句可以引用不同的表,如下所示:
  
  DELETE products ;
  FROM mfg ;
  WHERE mfg.productID = products.productID;
  AND mfg.discontinued = .t.
  這個DELETE語句刪除mfg表中所有不再生産的産品。
  另一個關聯UPDATE語句示例如下:
  
  UPDATE products ;
  SET unitprice = mfg.msrp *.90 ;
  FROM mfg ;
  WHERE mfg.productID = products.productID 
  這條UPDATE語句將零售産品的價格打了九折。可能你會問:它支持子查詢嗎?當然支持。但使用的時候要格外小心。因爲假如子查詢沒有返回任何記錄,那將會返回一個值爲NULL的空記錄。而這恰恰不是你所希望得到的結果。如下所示:
  
  UPDATE products ;
  SET unitprice = ; 
  (SELECT ( msrp *.90 ) ;
  FROM mfg ;
  WHERE mfg.productID = products.productID)
  這條UPDATE語句的作用與上條基本相似,但假如子查詢中的産品沒有找到的話,那unitprice將被置爲NULL。
  視圖與查詢設計器
  盡管新版本增強了子查詢功能,但不幸的是在視圖與查詢設計器中並不支持這種增強功能。並且由于SQL中的IN子句中的元素數目取消了硬編碼的限制,但視圖與查詢設計器中並不知道,因此假如你使用設計器,那IN子句還是只支持24個元素。
  增強的UNION操作符
  由于聯結的數量沒有了硬編碼的限制,你可以在INSERTINTO子句的結果集中使用UNION。也可以在使用UNION的同時使用ORDERBY子句。
  性能
  不管你是訪問遠程數據還是依靠于它強大的本地數據庫引擎,Visual FoxPro始終將性能考慮在第一位。Visual FoxPro 9進一步地增強了數據引擎的功能。
  二進制索引
  這種新型的索引使用方法如下:
  INDEX ON DELETED() TAG DELETED BINARY
  這種索引能與任何非空的邏輯表達式一起使用。除此之外,FOR表達式、ASCENDING、DESCENDING、UNIQUE或CANDIDATE要害字不能與它一起使用。
  二進制索引並不支持SET ORDER TO命令,而且INDEXON命令會將當前的order設爲0。但你可在Seek語句中使用二進制索引。
  二進制索引最大的優勢在于它的索引文件大小。以一個包含800萬條記錄的表爲例,它的二進制索引文件的大小差不多爲表大小的三十分之一。尺寸越小意味著在執行APPEND和REPLACE操作時I/O處理速度越快,但遺憾的是所有的Rushmore優化技術目前都還不支持二進制索引。
  假如SQL語句返回的記錄起過表中總記錄的三分之一的話,那Rushmore將得到很好的發揮(當所有的記錄都命中的話會提高92%的速度)。假如SQL語句返回的記錄低于總記錄的三分之一,那Rushmore將變得很慢(假如沒有記錄命中的話會降低兩倍的速度)。
  在Visual FoxPro 9中,將DELETE語句設置爲二進制索引是一種增強性能的簡單方法。但要注重版本的問題,因爲以前的版本並不支持這種新的索引方式。
  Rushmore優化技術
  新版本中有使用了大量的Rushmore優化技術,例如對TOPN[PERCENT]作了優化,這樣便能提供更好的性能。它一般與ORDER BY子句配合使用,返回前N個或者前百分比數目的記錄。在Visaul FoxPro 9中它減少了內排序操作和文件I/O操作,使得執行這種類型的語句占用更少的內存,並且正如此語句所言,它只返回確切的前N個記錄。
  在以前的版本中,假如要統計一個班級總分排在前十名的學生,但中間存在並列名次的話,那結果會返回多于10個的記錄。
  在適當的情況下,Visual FoxPro 9將在FOR DELETED()子句和FOR NOT DELETED()子句中使用過濾索引來對MIN()和MAX()這兩個聚集函數進行優化,可以提高MIN()和MAX()的計算速度。
  假如LIKE模糊查詢語句中的條件以“%”爲結尾,那查詢速度也將得到很大提高(請注重,“%”只能出現在查詢條件的結尾,而不能出現在其它地方,否則優化無效)。這種優化的結果等同于普通WHERE子句查詢的速度。
  更多的智能索引技術
  Visual FoxPro 9比以前的版本更智能化,它充分地讓索引獲得Rushmore的優化技術,如下所示:
  
  INDEX ON DELETED() TAG DELETED 
  以上語句自動對NOTDELETED()和DELETED()條件進行優化,不用你添加一條INDEX ON NOTDELETED()來實現。
  這裏有個特例,就是當索引過過濾表達式采用了FORNOTDELETED()作爲Rushmore的優化,並且SETDELETED設爲ON的話,那就無須爲NOTDELETED()作優化。(王朝網路 wangchao.net.cn)

沒有留言:

張貼留言