Loading

Die Leistung von SOQL-Abfragen mit einem benutzerdefinierten Index verbessern

Veröffentlichungsdatum: Apr 6, 2021
Beschreibung

SOQL-Abfragen müssen selektiv sein, insbesondere für Abfragen innerhalb von Triggern, um die beste Leistung zu erzielen. Um lange Ausführungszeiten zu vermeiden, können nicht selektive SOQL-Abfragen vom System abgebrochen werden. Entwickler erhalten eine Fehlermeldung, wenn eine nicht selektive Abfrage in einem Trigger gegen ein Objekt ausgeführt wird, das mehr als 200.000 Datensätze enthält. Im Folgenden erfahren Sie, wie Sie den Fehler vermeiden und die Abfrage selektiv gestalten können. 
Lösung

Wichtiger Hinweis: 

Obwohl alle Anstrengungen unternommen wurden, damit dieser Artikel die Funktionsweise des Salesforce SOQL Query Optimizers auf hohem Niveau erklärt, kann sich sein Verhalten ohne Vorankündigung ändern, um zusätzliche Leistungsverbesserungen zu ermöglichen. Entwicklern wird empfohlen, die Ansicht „Abfrageplan“ (verfügbar seit Summer '14) in der Entwicklerkonsole zu verwenden, damit sie nicht selektive Abfragen aufgrund der Informationen abstimmen können, die der Optimizer zum Zeitpunkt der Generierung des Abfrageplans für die betroffene SOQL-Abfrage bereitstellt.

Zusätzlich können Indizes Kosten für DML erhöhen und/oder in einigen Fällen muss der Query Optimizer Dinge basierend auf Indizes anders ausführen, was sich auf die Leistung auswirken kann.



Selektive SOQL-Abfragekriterien


Eine Abfrage ist selektiv, wenn sich einer der Abfragefilter auf ein indiziertes Feld bezieht und der Abfragefilter die resultierende Anzahl von Zeilen unter einen systemdefinierten Schwellenwert reduziert. Die Leistung der SOQL-Abfrage verbessert sich, wenn zwei oder mehr in der WHERE-Klausel verwendete Filter die genannten Bedingungen erfüllen.

Der Selektivitätsschwellenwert beträgt 10 % der Datensätze für die erste Million Datensätze und weniger als 5 % der Datensätze nach der ersten Million, bis zu einem Maximum von 333.000 Datensätzen. Unter bestimmten Umständen, z. B. bei einem Abfragefilter, der ein indiziertes Standardfeld ist, kann der Schwellenwert höher sein. Außerdem kann sich der Selektivitätsschwellenwert ändern.



Überlegungen zum benutzerdefinierten Index für selektive SOQL-Abfragen

Die folgenden Felder werden standardmäßig indiziert:
  • Primärschlüssel (Felder „ID“, „Name“ und „Inhaber“).
  • Fremdschlüssel (Nachschlage- oder Master-Detail-Beziehungsfelder).
  • Audit-Daten (z. B. SystemModStamp). 
  • Benutzerdefinierte Felder, die als „Externe ID“ oder „Eindeutig“ markiert sind.
       

Der Salesforce-Support kann auf Anfrage benutzerdefinierte Indizes für Kunden hinzufügen.

Achten Sie beim Anlegen eines Vorgangs beim Support darauf, dass Sie die SOQL-Abfrage, die das zu indizierende Feld enthält, als Filter in die WHERE-Klausel aufnehmen. Achten Sie auch darauf, eventuell vorhandene Bindewerte einzuschließen. 
Prüfen Sie die Checkliste in SOQL-Abfrage selektiv machen, bevor Sie einen Supportvorgang erstellen.
Sie können auch bestimmen, welche Felder indiziert werden können, indem Sie sich auf SOQL-Abfrage selektiv machen beziehen und die Abfrageplan-Analyse in der Developer Console wie hier erwähnt durchführen: Abfrageplan-Tool
Ein benutzerdefinierter Index auf die am wenigsten häufig vorkommenden Werte von Kontrollkästchenfeldern würde den größten Nutzen für die Leistung bringen und im Allgemeinen auf eine selektive Abfrage hindeuten.  

Ein benutzerdefinierter Index lässt sich für diese Art von Feldern nicht erstellen:
  • Auswahllisten mit Mehrfachauswahl.
  • Währungsfelder in einer Organisation mit mehreren Währungen.
  • Lange Textfelder. 
  • Binäre Felder (Felder vom Typ Blob, Datei oder verschlüsselter Text). 
Hinweis: Es kann vorkommen, dass neue, in der Regel komplexe Datentypen zu Salesforce hinzugefügt werden und dass solche Feldtypen keine benutzerdefinierte Indizierung zulassen.
       

Gewöhnlich wird in den folgenden Fällen kein benutzerdefinierter Index verwendet:
  • Der oder die abgefragten Werte überschreiten den oben genannten systemdefinierten Schwellenwert.
  • Der Filteroperator ist ein negativer Operator wie NOT EQUAL TO (oder !=), NOT CONTAINS und NOT STARTS WITH.
  • Im Filter wird der Operator CONTAINS verwendet und die Anzahl der zu durchsuchenden Zeilen übersteigt 333.000. Das liegt daran, dass der Operator CONTAINS einen vollständigen Index-Scan erfordert. Beachten Sie außerdem, dass sich dieser Schwellenwert ändern kann.
  • Beim Vergleich mit einem leeren Wert (Name != '').
Hinweis: Es gibt andere komplexe Szenarien, in denen benutzerdefinierte Indizes nicht verwendet werden. Wenden Sie sich an Ihren Salesforce-Ansprechpartner, wenn Ihr Szenario von diesen Fällen abweicht oder wenn Sie weitere Unterstützung bei nicht selektiven Abfragen benötigen.



Beispiele für selektive SOQL-Abfragen

Um besser zu verstehen, ob eine Abfrage über ein großes Objekt selektiv ist oder nicht, wollen wir einige Abfragen analysieren. Für diese Abfragen nehmen wir an, dass es über 200.000 Datensätze (einschließlich vorübergehend gelöschter Datensätze, d. h. gelöschter Datensätze, die sich noch im Papierkorb befinden) für das Objekt des Accounts gibt.


Abfrage 1:

SELECT Id FROM Account WHERE Id IN (<list of account IDs>)
Die WHERE-Klausel bezieht sich auf ein indiziertes Feld (Id). Wenn SELECT COUNT() FROM Account WHERE Id IN (<list of account IDs>) weniger Datensätze als den Selektivitätsschwellenwert liefert, wird der Index auf Id verwendet. Dies wird typischerweise der Fall sein, da die Liste der IDs nur wenige Datensätze enthält.


Abfrage 2:

SELECT Id FROM Account WHERE Name != ''
Da Account ein großes Objekt ist, obwohl „Name“ indiziert ist (Primärschlüssel), gibt dieser Filter die meisten Datensätze zurück und macht die Abfrage nicht selektiv.
 

Abfrage 3:

SELECT Id FROM Account WHERE Name != '' AND CustomField__c = 'ValueA'
Hier müssen wir sehen, ob jeder Filter, wenn er einzeln betrachtet wird, selektiv ist. Wie wir im vorherigen Beispiel gesehen haben, ist der erste Filter nicht selektiv. Konzentrieren wir uns also auf den zweiten. Wenn die Anzahl der Datensätze, die von SELECT COUNT() FROM Account WHERE CustomField__c = ‚ValueA‘ zurückgegeben werden, kleiner ist als der Selektivitätsschwellenwert und CustomField__c indiziert ist, ist die Abfrage selektiv.

Abfrage 4:

SELECT Id FROM Account WHERE FormulaField__c = 'ValueA'
Die folgenden Regeln müssen erfüllt sein, um ein Formelfeld zu indizieren:
  • Die Formel enthält nur Felder aus einem einzelnen Objekt (keine Beziehungsfelder).
  • Das Formelfeld verweist auf keine nicht deterministischen Funktionen (z. B. SYSDATE).
  • Das Formelfeld verweist auf keine nicht unterstützten Felder für die Aufnahme in Indizes. Diese Liste ist nirgends speziell dokumentiert (es gibt viele Sonderfälle), aber in Spring 12 (176) wurde createdById nicht unterstützt, jedoch wird es in Summer 12 (178) unterstützt. Das Gleiche gilt für CreatedDate.
  • Das Formelfeld enthält keine Verweise auf Primärschlüssel (z. B. Id) 
  • Das Formelfeld verwendet nicht die Funktion TEXT(<picklist-field>)
  • Wenn die Formel auf ein Nachschlagefeld verweist, darf die Option „What to do if the lookup record is deleted?“ (Was tun, wenn der Lookup-Datensatz gelöscht wird?) nicht auf „Clear the value of this field“ (Den Wert dieses Feldes löschen) gesetzt sein.

 

Hinweis: Die Leistung der SOQL-Abfrage wird vom Salesforce Support analysiert. Wenn sie die Kriterien erfüllt, wird der Index erstellt.

Nummer des Knowledge-Artikels

000385213

 
Laden
Salesforce Help | Article