こんにちは、管理人の@Salesforce.Zです。
System.QueryException: Non-selective query against large object type
sandboxではエラーが出なかったが本番で発生しましたよー。
あまり、見る機会のないエラーと思います。
★ Non-selective queryの原因 ★ Non-selective queryの対策
目次
Non-selective query
System.QueryException: Non-selective query against large object type (more than 200000 rows). Consider an indexed filter or contact salesforce.com about custom indexing
caused by: System.QueryException: Non-selective query against large object type (more than 200000 rows). Consider an indexed filter or contact salesforce.com about custom indexing. Even if a field is indexed a filter might still not be selective when: 1. The filter value includes null (for instance binding with a list that contains null) 2. Data skew exists whereby the number of matching rows is very large (for instance, filtering for a particular foreign key value that occurs many times)
原因
10万件超えているオブジェクトに対して、トリガ内で、カスタム項目を条件にし、SELECT文を発行するとエラーになります
対策
SOQLの条件分(Where句)に設定する条件を、カスタム項目に外部IDを設定すると内部インデックスが作成されるぽくなり、10万件超えてもエラーが出なくなる。
リファレンス
注意点
・外部IDで対応する場合、1オブジェクトに外部IDの指定は3つまで。
・SOQL の実行結果が 200,000 レコード未満であったとしても、実行計画が SOQL の効率を確認した結果、非効率なクエリであると判断した際に Non-selective query against large object type (more than 100000 rows) というエラーが出力されます。
インデックスを使用してもセレクティブでなくなる例外
null 行に対するクエリ — 項目が空または null であるレコードを探すクエリ
SELECT Id, Name FROM Account WHERE Custom_Field__c = null
否定的な絞り込み演算子 — クエリ内での !=、NOT LIKE、EXCLUDES などの演算子の使用
SELECT CaseNumber FROM Case WHERE Status != ‘New’
先頭のワイルドカード
SELECT Id, LastName, FirstName FROM Contact WHERE LastName LIKE ‘%smi%’
比較演算子を使用したテキスト項目
SELECT AccountId, Amount FROM Opportunity WHERE Order_Number__c > 10
終わりに
クエリ実行プランツールを使用しましょう
1.[設定] で、[<あなたの名前>] > [開発者コンソール] をクリックして開発者コンソールを開きます。
2.開発者コンソールで、[Help (ヘルプ)] > [Preferences (設定)] を選択します。
3.[Enable Query Plan (クエリプランを有効化)] を選択し、true に設定されていることを確認します。
4.[Save (保存)] をクリックします。
5.[Query Editor (クエリエディタ)] タブで、[Query Plan (クエリプラン)] ボタンが [Execute (実行)] ボタンの横に表示されていることを確認します。