2017-06-09 3 views
0

Ich versuche, diese Abfrage:Apex Abfrageoptimierung

List<Account> onlyRRCustomer = [SELECT 
            ac.rr_First_Name__c, 
            ac.rr_Last_Name__c, 
            ac.rr_National_Insurance_Number__c, 
            ac.id, 
            ac.rr_Date_of_Birth__c 
           FROM 
            Account ac 
           WHERE 
            ac.rr_National_Insurance_Number__c IN :uniqueNiInputSet 
            AND RecordTypeId = :recordTypeId]; 

Es gibt mir eine Fehlermeldung:

SELECT ac.rr_First_Name__c, ac.rr_Last_Name__c, ac.rr_National_Insurance_Number__c, ac.id, ac.rr_Date_of_Birth__c FROM Account ac WHERE (ac.rr_National_Insurance_Number__c = :tmpVar1 AND RecordTypeId = :tmpVar2) 10:12:05.0 (11489528)|EXCEPTION_THROWN|[49]|System.QueryException: Non-selective query against large object type (more than 200000 rows). Consider an indexed filter or contact salesforce.com about custom indexing.

Ich verstehe uniqueNiInputSet.size() ~ 50, so ist es kein Problem, aber für Dieser Datensatztyp enthält möglicherweise mehr Datensätze.

Also, wenn ich die Position geändert, wird das funktionieren? Bedeutet, zuerst der Recordtype und dann der NIset in where-Klausel. Gibt es eine Reihenfolge, wie where-Klausel in SF ausgewählt werden. Also, es wird nur für 50 Mitglieder suchen und dann innerhalb von 50 wird es nach dem bestimmten Datensatztyp suchen?

Antwort

0

Das bedeutet nur, dass das Skript zu lange dauert, um ausgeführt zu werden. Möglicherweise müssen Sie dies in eine @ future-Methode verschieben oder sie mithilfe von Database.Batchable ausführen.

Ich glaube nicht, dass die Reihenfolge in SOQL wichtig ist, ich denke, es versucht nur, zu viele Datensätze zurückzugeben.

0

Eine nicht selektive Abfrage bedeutet, dass Sie eine Abfrage für eine Tabelle ausführen, die eine große Anzahl an Datensätzen enthält und Ihre Abfrage nicht spezifisch genug ist. Sie können mit der Salesforce-Unterstützung arbeiten, um zu versuchen, dies zu beheben, entweder durch die Erstellung zusätzlicher Back-End-Indizes oder indem Sie die Abfrage selektiver machen. Um ehrlich zu sein, Ihre Abfrage sieht bereits sehr selektiv aus, Sie verwenden nicht LIKE oder IN. Sie sollten auch Ihre selektivsten Bedingungen zuerst angeben (was zu einer gezielteren Abfrage Ihrer Datensätze führt).
Ich weiß, es sollte nicht wichtig sein, aber ich würde auch Ihre Bedingungen aus den Klammern bewegen. Wenn es noch andere Felder gibt, nach denen Sie filtern können, kann das hilfreich sein. Manchmal müssen Sie tatsächlich neue Felder erstellen und sie ausfüllen, um Ihre Abfragen selektiver zu machen. Wenn es sich bei rr_National_Insurance_Number__c um ein Formelfeld handelt, möchten Sie es möglicherweise in ein Textfeld ändern und stattdessen Workflow oder Apex füllen. Formelfelder erfordern zusätzliche Zeit auf den Servern, um zu berechnen.

SELECT rr_First_Name__c, rr_Last_Name__c, rr_National_Insurance_Number__c, id, rr_Date_of_Birth__c 
FROM Account 
WHERE new_custom_field__c = TRUE 
AND rr_National_Insurance_Number__c = :tmpVar1 
AND RecordTypeId = :tmpVar2 
0

Ihre Abfrage ist nicht selektiv. Für eine Standard-Indizes beträgt 30% für die erste Million Datensätze und 15% der Datensätze über eine Million bis zu 1 Million Datensätze insgesamt. Für und "AND" Abfrage jedes Individuum, wo Kriterien selbst selektiv sein müssen siehe this Quick Reference Spickzettel. In der Regel versuchen

rr_National_Insurance_Number__c

eine externe ID zu machen, das es ein indiziert durch Salesforce standardmäßig machen und wiederholen Sie abfragen. Datensatztypen sind bereits standardmäßig indiziert. Wenn das Ergebnis aufgrund der Anzahl der zurückgegebenen Ergebnisse weiterhin nicht selektiv ist, versuchen Sie, die Anzahl der Ergebnisse zu begrenzen, indem Sie ein Feld wie CreatedDate verwenden, um den Gültigkeitsbereich der Abfrage zu begrenzen.