本篇參考:html
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=1spa
咱們在作項目得時候,一般會有需求是根據不少入力條件進行SOQL查詢,而後展現 List。好多程序最開始跑的是沒有問題得,當數據達到必定數據量好比百萬級別之後,可能特別慢,或者更很差的狀況下,直接崩潰了。針對這種狀況有不少種可能狀況致使,其中最多見的一種狀況是:你當前的SOQL 語句不是selective的,或者是selective的狀況下沒有達到最大的優化。那什麼樣的SOQL語句是selective的,有什麼定義或者特色去區分,如何去更好的優化SOQL呢?接下來的內容就拋磚引玉,引出相關的話題。code
一. selective的SOQL語句orm
咱們想肯定一個SOQL是否爲selective的,當前SOQL應該具備如下的特徵:server
1. where後面的filter的字段應該最少有一個索引字段(字段應該是 indexed的)。索引字段的概念咱們後面會單獨做爲一個部分來說;htm
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。這些列什麼含義,如何去理解?
以上的就是關於查詢的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。針對上面得各個點講的都很淺,感興趣得查看上方提供得各個官方得文檔以便更深刻學習。篇中有錯誤歡迎指出,有不懂歡迎留言。