跳轉到內容

WebObjects/EOF/使用 EOF/EOF 效能調優

來自 Wikibooks,開放世界的開放書籍

EOF 效能調優

[編輯 | 編輯原始碼]

EOF 為你做了很多很棒的事情。但很多人在一些事情上會遇到困難;比如,一個關係型到物件的對映庫可能會有嚴重的開銷。在大型複雜物件模型中,一個常見的經驗是,人們會對他們的物件建模,然後進行大量獲取,並發現獲取大量 EO 的速度非常慢(相對於他們使用 JDBC 或直接 SQL 的預期速度)。將東西帶入 EO 的開銷會有所不同,但看到比原始 SQL 慢 100 倍的速度下降是完全有可能的;對於許多問題來說,這實在是一個太大的代價。那麼該怎麼辦呢?

以下是一些可以採取的方法來改進;

減輕物件負擔

[編輯 | 編輯原始碼]

在 R/O 系統中,最大的代價是將新物件(專案)與其他快取版本(快照)進行比較,並整合和解決任何更改。因此,新增物件意味著你會產生這種代價。儘管如此,如果你減輕物件的負擔,還是有一些微不足道的益處。

你的 EO 不需要對錶中的所有內容進行建模。你也可以有多個對映到同一表的 EO。EO 的寶貴之處在於你可以對關係進行建模,並且可以進行關係遍歷;但這些關係也會產生成本。如果你減少了不需要的關係的物件,它們就會載入得更快;對你不需要的屬性也是如此。你甚至可以更進一步;根據你當前的操作,可以有多種 EO 版本。因此,可以使用一個 EO 來獲取特定獲取所需的所有屬性和關係,另一個變體用於不同型別的獲取;最後,你需要完整版本的 EO,只有在你需要檢視或編輯所有資訊的情況下才載入。因此,你的大部分 EO 集合都比用於大型編輯的 EO 更輕量級,更具針對性。

還有其他技術,例如在 EOModeler 中使用 little lock 屬性,使更多專案對 EOF 不透明(或不可變)。EOF 會將這些帶有鎖的屬性與快照中的物件進行比較,以確定物件是否陳舊;因此減少需要比較的屬性可以提高速度。有些人將這種方法發揮到極致,將所有/大多數屬性設定為解鎖,並使用一個時間戳作為唯一關鍵專案;然後,如果任何屬性發生變化,該時間戳也會發生變化,EOF 仍然可以管理快照,但只需要管理更少的屬性。但這似乎更像是為了節省 EOF 在每個物件上的執行時維護而進行的編碼。

但關鍵是,EO 越輕量級、越簡單,速度就越快。然而,主要的代價是在序列化/同步方面;因此,在大多數情況下,回報可能不足以證明為建立這些“最佳化”而採取的措施的合理性。

調整模型

[編輯 | 編輯原始碼]

當你打算使用一個關係型到物件的對映庫(如 EOF)時,你應該期望這會改變你的需求;足以讓你能夠調整你的模型以適應這個工具。

如果獲取 EO 很重/很慢,那麼通常你獲取的物件越少,你的系統性能就越好。因此,如果你將許多小的表合併和反規範化成幾個更大的表,你將減少 EO 的載入次數,並且可能減少對所有這些小片段及其關係的所有錯誤和關係管理的處理;這會導致效能提升。

你可以透過扁平化關係來做到這一點,或者在資料庫中使用檢視使事物看起來比實際更扁平;或者你可以直接對模型進行扁平化。根據你的需求,可以對每種方法進行論證。

你甚至可以更進一步,開始將複雜的資料結構和關係移入你自己管理的 blob 中。這將 EOF 從管理這些資料結構和關係中解放出來,並且通常可以加快速度;但代價是你需要承擔更多的程式碼維護工作,而且反規範化可能會對設計造成負面影響,所以你應該謹慎地選擇走這條路。

原始行(延遲提升)

[編輯 | 編輯原始碼]

加快訪問速度的最重要技術之一是使用原始行;或者進行延遲提升。基本上,原始行獲取是一種方法,允許你進行資料庫獲取,返回一個數據結構(鍵值對陣列),而不是獲取並將資料結構提升為一個完整的物件(EO)。這種輕量級的獲取所需時間更少,對於大型集合來說要好得多。

然後,在使用這些集合的頁面上可以使用原始行,並且你只在需要處理整個物件(及其所有複雜性)的頁面上將物件從集合中提升為重量級 EO。

原始 SQL

[編輯 | 編輯原始碼]

由 EOF、EOModeler 或其他工具生成的獲取通常沒有由人類生成的獲取那麼最佳化;如果它們是最佳化的,那麼機器就不需要我們了,它們可以自己程式設計。透過自己建立原始 SQL,你通常可以自己調整和最佳化獲取,以只獲取你感興趣的表的部分內容(列和/或行);再次提高效能,並對最需要調整的區域進行調整。

另一個重大效能提升是,如果你將關係中需要選擇的欄位作為原始行的一部分進行選擇,就可以遍歷關係。這也會減少事務負載(一些資料庫在更便宜的許可證下只允許 100 TPM),並且通常會提高獲取速度,因為所有資料都在一次 SQL 查詢中透過多表 SELECT 語句(JOIN)進行獲取。你還可以指揮你的 EOModel,以確定關係執行內部聯接還是外部聯接,這對於檢查資料完整性來說是一個很大的好處。(檢視一些 SQL 網站以瞭解 INNER、LEFT OUTER、OUTER 和 RIGHT OUTER 聯接,看看一些優秀的資料收集方法)

靠近資料庫(儲存過程)

[編輯 | 編輯原始碼]

雖然使用資料庫(使用儲存過程等)似乎違背了資料庫抽象層的目的之一;但這可能是必要的或明智的步驟。

儲存過程可以在資料庫級別完成一些事情,這些事情要快得多,並且可以極大地減輕應用程式伺服器的負載。代價是缺乏資料庫獨立性;並且你必須學習你正在使用的資料庫的詳細資訊。但是,一些精心放置的儲存過程可以帶來數量級的差異。

快取是一個需要單獨討論的問題。雖然 EO 速度較慢,但它們確實會進行快取——因此後續獲取(重新獲取)的速度比第一次(主要獲取)快得多。這對不可變(靜態)資料非常有效。對動態資料效果較差。儘管如此,您仍然可以利用除預設快取行為之外的其他行為。您可以將不可變資料的原始行獲取到您自己的陣列中,並管理您自己的這些資料的快取。您也可以將複雜或複合屬性放入快取屬性中,並獲取該專案,而不是即時獲取該專案或不斷地從所有源部分重新計算該專案(預先構建一些計算或集合)。

因此,快取不僅意味著 WO+EOF 應該快取,而且您可能還需要考慮可以快取哪些內容,以減輕各種獲取的負擔。

預取/提示

[編輯 | 編輯原始碼]

現在,各種預取和提示並沒有真正為您節省時間,因為您仍然需要載入所有物件併為其支付相同的載入時間;但它們可以改變您支付這些時間的位置。有時,即使它不改變實際效能,這也能顯著提高感知效能。使用者可能會容忍在一個頁面上 5 或 10 秒的延遲,如果他們與之互動的接下來的 10 件事都更快;反之亦然。因此,瞭解使用者想要做什麼,以及他們如何嘗試去做,並相應地進行調整非常重要。

減少您的資料集

[編輯 | 編輯原始碼]

這可能聽起來很明顯,但儘可能減少您的資料集。例如,沒有一個頁面應該真正顯示 5,000 個元素——這需要花費太長時間來載入和顯示。最好使用獲取限制或類似的行為,儘可能向用戶顯示一組較小的資料;然後使用各種技術儘可能少地獲取資料。資料集越小,通常可以越快地處理它。

這些只是您可以想到的加快 EO 獲取速度的一些技術。

有些人可能會說,如果您必須做所有這些事情,那麼您就是在為 EOF 做所有工作;或者您在最佳化程式碼上花費的時間和它最初為您節省的時間一樣多。雖然在極少數情況下可能是這樣;但一般來說,會發生這種情況,EOF 使您能夠非常快速和輕鬆地建立解決方案;然後,您回頭去學習瓶頸在哪裡(分析),並調整這些區域,直到它們在您的要求下表現得足夠好。這允許 RAD(快速應用程式開發)工具的優勢,以及更低級別工具的功能和速度;如果您願意花時間調整需要調整的區域。而且,許多類別的應用程式可能只需要很少的調整。

供應商特定

[編輯 | 編輯原始碼]

有關供應商特定的效能調整,請參閱供應商特定部分

分析 EOF

[編輯 | 編輯原始碼]

安喬·克蘭克

[編輯 | 編輯原始碼]

看看 Project Wonder 中的 ERXAdaptorChannelDelegate。

查克·希爾

[編輯 | 編輯原始碼]

EOModeler 為多對多聯接表生成的 SQL 不允許聯接的完全最佳化。多對多聯接表僅生成一個索引,該索引是兩個列的複合鍵。

例如,

 CREATE TABLE "GROUP_FILE" (
   "FILE_PKEY" NUMERIC NOT NULL,
   "GROUP_PKEY" NUMERIC NOT NULL
 );
 
 ALTER TABLE "GROUP_FILE"
   ADD PRIMARY KEY
     ("GROUP_PKEY","FILE_PKEY")
   NOT DEFERRABLE INITIALLY IMMEDIATE;

此索引只能用於最佳化索引中第一列上的聯接(出於某種原因,這是表中的第二列)。由於缺少另一列的索引,因此在另一列上聯接時會導致表掃描。這種聯接發生在遵循多對多關係時。例如,group.files() 將為 files() 中的每個元素生成類似於此的 SQL

 SELECT f.* 
 FROM FILE f, 
      GROUP g,
      GROUP_FILE gf
 WHERE
       f.PKEY = gf.FILE_PKEY AND
       g.PKEY = gf.GROUP_PKEY AND
       g.PKEY = 10;

只有 GROUP_PKEY 有索引,可用於最佳化此查詢。FILE_PKEY 上的聯接 (f.PKEY = gf.FILE_PKEY) 未最佳化,會導致表掃描。您需要為此手動新增索引

 CREATE INDEX GROUP_FILE_FILE_PKEY
      ON GROUP_FILE (FILE_PKEY);

如果聯接表中有許多行,這將產生真正巨大的差異。

華夏公益教科書