Salesforce 大數據量處理篇(二)Index


本篇參考:

https://developer.salesforce.com/docs/atlas.en-us.202.0.salesforce_large_data_volumes_bp.meta/salesforce_large_data_volumes_bp/ldv_deployments_infrastructure_indexes.htm

https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E5%BA%93%E7%B4%A2%E5%BC%95/8751686?fr=aladdin

https://help.salesforce.com/articleView?id=000325257&type=1&mode=1

https://help.salesforce.com/articleView?id=000334796&type=1&mode=1

https://developer.salesforce.com/blogs/engineering/2013/09/collecting-selectivity-statistics-for-force-com-queries.html

我們在做項目得時候,通常會有需求是根據很多入力條件進行SOQL查詢,然后展示 List。好多程序最開始跑的是沒有問題得,當數據達到一定數據量比如百萬級別以后,可能特別慢,或者更不好的情況下,直接崩潰了。針對這種情況有很多種可能情況導致,其中最常見的一種情況是:你當前的SOQL 語句不是selective的,或者是selective的情況下沒有達到最大的優化。那什么樣的SOQL語句是selective的,有什么定義或者特點去區分,如何去更好的優化SOQL呢?接下來的內容就拋磚引玉,引出相關的話題。

一. selective的SOQL語句

我們想確定一個SOQL是否為selective的,當前SOQL應該具有以下的特征:

1. where后面的filter的字段應該最少有一個索引字段(字段應該是 indexed的)。索引字段的概念我們后面會單獨作為一個部分來講;

2. 如果filter的字段包含了索引字段,我們將確定一下當前的SOQL返回了多少條數據。針對返回的數據的條數,我們需要看當前的索引字段是標准的索引還是自定義索引。對於標准索引,閾值是第一個百萬目標記錄的30%,以及第一個百萬目標記錄之后所有記錄的15%。此外,標准索引的選擇性閾值最大為100萬條總目標記錄,只有在總記錄數超過560萬條時才能達到。對於自定義索引,選擇性閾值為第一個百萬目標記錄的10%,以及第一個百萬目標記錄之后所有記錄的5%。此外,自定義索引的,只有在這個表記錄數超過5,6百萬條的情況下,選擇性閾值最大為333333條目標記錄被認為是selective的。

(注:閾值我們可以理解成臨界值,即當前的SOQL語句在當前系統通過當前 filter能查詢出來的最大值)

舉個例子。我們搜索一個自定義表,目前數據量有30萬條,因為他是100萬條以內,所以如果使用了標准的索引,閾值 = 300000 * 30% = 90000條,也就是說當查詢的SQL返回的數據如果使用標准索引只要返回的數量在90000條以內,就代表當前的SOQL是selective的。針對自定義要求是10% * 300000 = 30000條,即返回數據在這個以內代表當前的數據是selective的。

所以一言以蔽之,selective的SOQL的語句具備的特性有兩個: 1. filter包含 索引字段;2.查詢出來的數據滿足當前要求的閾值。只有當前的SOQL是selective的情況下,我們才可以使用工具去進行優化。什么工具呢?看下面。

二. Query Plan Tool

概念和使用暫且不提,先看一下Query Plan Tool如何啟用以及在哪里。我們打開 develop console,點擊menu部分的help,選擇 Preferences,然后彈出的地方我們便可以看到針對 Enable Query Plan的設置,默認就是true代表已經啟用,這樣我們在下面的 Query Editor中輸入相關的SOQL以后,便可以使用 Query Plan Tool來了解官方對當前的SOQL的建議了。

使用Query Plan Tool用於SOQL運行緩慢的檢測以及優化建議,所以不是所有的場景都需要了解他,當你的數據量特別大,當前SOQL運行特別緩慢,使用它。否則了解這個概念和工具就好。

我們先寫一個SQL看一下效果。下圖為使用 Query Plan的效果圖。包含兩個大部分,上面的列表(Plan List)以及下面的Notes部分。

 我們看到每個Plan里面都會包括 Cardinality / Fields / Leading Operation Type / Cost / sObject Cardinality / sObject Type。這些列什么含義,如何去理解?

  • Cardinality(基數):使用 Leading Operation Type操作方式情況下,預估的返回的數據條數;
  • Fields:查詢優化器(Query Optimizer)中使用的索引字段。如果 Leading Operation Type是 索引的,則當前的列將會展示索引字段,如果是全表掃描的模式,則當前的這個列將展示空;
  • Leading Operation Type:Salesforce將用於優化查詢的主要操作類型。這里有4個值:
    1. Index:當前查詢的對象使用索引進行查詢;
    2. Sharing:當前的查詢將會使用索引進行查詢。當前的索引基於當前執行SQL的人的共享規則來決定的。如果有 sharing rule限制了user可以訪問的記錄情況下,salesforce可以根據這些共享規則去進行優化;
    3. TableScan:當前的查詢方式為查詢當前表的所有數據;
    4. Other:salesforce將使用內部的優化方式去查詢。
  • Cost:與Force.com查詢優化器的選擇性閾值相比,查詢的成本。 如果這個值大於1表示查詢不會是selective的。
  • sObject Cardinality:查詢當前對象大概的記錄數;
  • sObject Type:當前查詢表的 object的名字。

以上的就是關於查詢的Plan表的各個列的名詞解釋。下圖附上一張 Cost超過1的情況,因為查詢的 filter沒有索引字段,所以查詢非 selective,cost超過了1.

我們通過Notes等信息以及上面的表格便可以查看到對SOQL進行優化建議。細節得 Query Plan Tool介紹我們可以查看上方得鏈接中官方描述得文檔。上面我們提到了 selective的SOQL必須是包含索引字段,那么在salesforce的世界里面哪些是索引字段,怎么設置索引字段呢???

三. Index(索引)

索引這個概念不止針對salesforce的SOQL,其他的類似SQL server以及 Oracle都有索引的概念,查詢的filter中通過索引字段可以加快查詢的速度。具體的索引的含義也可以查看上面的百度百科的文檔。Salesforce針對索引字段有標准和自定義兩種。我們如何知道當前哪些字段是索引字段呢?只需要進入field中,查看Indexed這列信息即可,下圖展示Account表中的一些索引字段的截圖。

 1. 標准索引字段

salesforce針對幾乎所有的表的以下字段維護了索引。分別是:RecordTypeId 、 Division、 CreatedDate、Systemmodstamp (LastModifiedDate)、Name、Email (for contacts and leads)、Foreign key relationships (lookups and master-detail)、Salesforce記錄得 Record Id。也就是說表中的這些的字段,salesforce大部分已經自行維護了索引字段用來優化查詢,無需在進行設置索引。

2. 自定義索引字段

當然,一個項目不可能只使用標准字段,我們還是需要創建自定義字段去實現相關得自定義邏輯。針對自定義字段同樣可以設置成索引字段。當然不是所有得類型都可以設置索引字段,以下得類型salesforce不支持設置索引字段:multi-select picklists / text area (long) / text area (rich) / non-deterministic formula fields / encrypted text。編輯字段以后,勾選external Id外鍵以后,便成了被標記成索引得字段。外鍵僅可以Auto Number / Email / Number / Text類型中創建。當然,凡事不是那么絕對,如果需要在其他得字段類型中創建自定義得索引字段,包括標准字段,可以聯系salesforce得support人員,他們可以進行設置。

上面有一個描述是non-deterministic formula fields不支持創建索引字段得,並不是代表formula不支持索引,只是部分情況不支持。上方得index文檔中有具體描述,感興趣自行查看。

這里擴充兩個對大量數據的SOQL比較災難的兩個filter,又常常是我們經常用到的。一個是使用 formula字段進行 filter,一個是使用 null 進行filter。怎么樣,項目上使用的是不是很常見?數據量少的時候OK,當真正數據量達到一定程度,你會發現這兩種都是災難性的。因為這兩個默認的都是不帶索引的!!!如果項目中遇到了這兩種使用在filter中,並且數據量很龐大,找salesforce提support設置索引,salesforce可以針對 null單獨設置索引。比如我們針對某個自定義字段 XX__c設置了 index,我們的SOQL : 

select Id,Name from Account where XX__c = null

即使XX__c是索引字段也不行,需要額外的聯系salesforce,將這個字段設置顯示的 index用來支持null索引。

總結:當我們運行得SOQL隨着數據量增加而變緩慢或者超時等錯誤情況下,我們可以使用 Query Plan Tool去查看是否有優化得解決方案。了解哪些類型可以進行索引設置,掌握哪些條件可以滿足一個SOQL是 selective。針對上面得各個點講的都很淺,感興趣得查看上方提供得各個官方得文檔以便更深入學習。篇中有錯誤歡迎指出,有不懂歡迎留言。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM