Регистрация  |  Вход

Пробелы в знание SOQL

Всем привет!

Может ли кто нибудь помочь заполнить пробелы в понимание как работает база данных в apex и запросы к ней.

Не могу до конца понять, что будут возвращать такие запросы.

Например, когда пишется такой запрос

SELECT Id FROM Case WHERE Type =: 'something' OR Status =: 'something' OR AccountId =: 'accountId'

Оно вернет все записи где одно из этих условий соблюдается, вернет ли оно записи где будет совпадать несколько условий?
И можно ли как нибудь их отсортировать прям в запросе, например, если поставить LIMIT 100 то чтоб вернуло сначала те, где наибольшее число условий совпадает. Например что в этом листе из 100 оказало все записи у которых 3 поля совпадают, и только если таких нет то, чтоб оно искало где хотя бы одно из полей совпадает?

Посоветуйте, что можно почитать по этому поводу? Это основы того как в общем работает sql и базы данных?

Всем привет!

Может ли кто нибудь помочь заполнить пробелы в понимание как работает  база данных в apex и запросы к ней. 

Не могу до конца понять, что будут возвращать такие запросы. 

Например, когда пишется такой запрос 

SELECT Id FROM Case WHERE Type =: 'something' OR Status =: 'something' OR AccountId =: 'accountId'

Оно вернет все записи где  одно из этих условий соблюдается, вернет ли оно записи где будет совпадать несколько условий? 
И можно ли как нибудь их отсортировать прям в запросе, например, если поставить LIMIT 100 то чтоб вернуло сначала те, где наибольшее число условий совпадает. Например что в этом листе из 100 оказало все записи у которых 3 поля совпадают, и только если таких нет то, чтоб оно искало где хотя бы одно из полей совпадает? 

Посоветуйте, что можно почитать по этому поводу? Это основы того как в общем работает sql и базы данных? 
   
[quote="AntonB"]Посоветуйте, что можно почитать по этому поводу?[/quote]

https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_sosl_intro.htm

https://trailhead.salesforce.com/modules/apex_database/units/apex_database_soql

AntonB
Оно вернет все записи где одно из этих условий соблюдается, вернет ли оно записи где будет совпадать несколько условий?

Да и да.
Любой запрос можно проговорить по-русски чтобы понять что он делает.
В твоем случае получается:
Дай мне записи где Type равен "something" ИЛИ Status равен "something" ИЛИ AccountId равен "accountId".
Если бы ты был на месте базы данных чтобы ты ответил на эту просьбу?

AntonB
то чтоб вернуло сначала те, где наибольшее число условий совпадает

А вот это уже жопа. Чет мне не приходит на ум как это можно в одном запросе замутить.

Я бы делал по простому в лоб. Сначала выбрал все записи где все поля совпадают. Если их меньше 100 вернулось, то запросил бы записи где совпадают 2 поля в различных комбинациях. Если первый и второй запрос в сумме вернули меньше 100, то уже применил бы твой запрос выше.

[quote="AntonB"]Оно вернет все записи где одно из этих условий соблюдается, вернет ли оно записи где будет совпадать несколько условий? [/quote]
Да и да.
Любой запрос можно проговорить по-русски чтобы понять что он делает.
В твоем случае получается:
Дай мне записи где Type равен "something" ИЛИ Status равен "something" ИЛИ AccountId равен "accountId".
Если бы ты был на месте базы данных чтобы ты ответил на эту просьбу?

[quote="AntonB"]то чтоб вернуло сначала те, где наибольшее число условий совпадает[/quote]
А вот это уже жопа. Чет мне не приходит на ум как это можно в одном запросе замутить.

Я бы делал по простому в лоб. Сначала выбрал все записи где все поля совпадают. Если их меньше 100 вернулось, то запросил бы записи где совпадают 2 поля в различных комбинациях. Если первый и второй запрос в сумме вернули меньше 100, то уже применил бы твой запрос выше.

Dmitry Shnyrev
Если бы ты был на месте базы данных чтобы ты ответил на эту просьбу?

Ну да, получается, что вернет все где или одно или все из этих условий соблюдаются.

Dmitry Shnyrev
Я бы делал по простому в лоб. Сначала выбрал все записи где все поля совпадают. Если их меньше 100 вернулось, то запросил бы записи где совпадают 2 поля в различных комбинациях. Если первый и второй запрос в сумме вернули меньше 100, то уже применил бы твой запрос выше.

У меня вообще финальная цель такая, что мне надо вернуть все кейсы которые схожие с каким то одним, так скажем главным. Для того, чтобы понять схожие ли они у меня есть 7 полей, по которым я сравниваю. То как я делаю сейчас, это пишу запрос со всеми полями через OR, потом прогоняю их через цикл и считаю количество полей которые совпали с значением в поле главного кейса. В результате, у меня получается Map<Id, Integer> где я храню id похожего кейса и количество полей одинаковых с главным кейсом.
Проблема в том, что запрос в котором все поля через OR возвращает около 20к записей. И потом после этого еще кучу других вычислений и запросов надо делать по этому для некоторых кейсов бьет по cpu limit.

Какие есть вообще практики, в случае когда нужно обрабатывать большое количество данных для каждой записи? Я попытался сделать batch которая будет работать для каждой записи отдельно, но как я понимаю, это не самая лучшая практика.

[quote="Dmitry Shnyrev"]
Если бы ты был на месте базы данных чтобы ты ответил на эту просьбу?
[/quote] 
Ну да, получается, что вернет все где или одно или все из этих условий соблюдаются. 

[quote="Dmitry Shnyrev"]Я бы делал по простому в лоб. Сначала выбрал все записи где все поля совпадают. Если их меньше 100 вернулось, то запросил бы записи где совпадают 2 поля в различных комбинациях. Если первый и второй запрос в сумме вернули меньше 100, то уже применил бы твой запрос выше.[/quote]

У меня вообще финальная цель такая, что мне надо вернуть все кейсы которые схожие с каким то одним, так скажем главным. Для того, чтобы понять схожие ли они у меня есть 7 полей, по которым я сравниваю. То как я делаю сейчас, это пишу запрос со всеми полями через OR, потом прогоняю их через цикл и считаю количество полей которые совпали с значением в поле главного кейса. В результате, у меня получается Map<Id, Integer> где я храню id похожего кейса и количество полей одинаковых с главным кейсом. 
Проблема в том, что запрос в котором все поля через  OR возвращает около 20к записей. И потом после этого еще кучу других вычислений и запросов надо делать по этому для некоторых кейсов бьет по cpu limit.

Какие есть вообще практики, в случае когда нужно обрабатывать большое количество данных для каждой записи? Я попытался сделать batch которая будет работать для каждой записи отдельно, но как я понимаю, это не самая лучшая практика. 

AntonB
Какие есть вообще практики, в случае когда нужно обрабатывать большое количество данных для каждой записи?

Чтоб обработать большое количество даннных, best practice это исползование Batch Apex.
Default batch size 200, максимум 2000 и можно исползовать Global переменные (List/Map).

Надеюсь что в будущем добавят Duplicate Management (Matching rule + Duplicate rule) в объект Case

Idea:
https://success.salesforce.com/ideaView?id=08730000000DjN5AAK

[quote="AntonB"]Какие есть вообще практики, в случае когда нужно обрабатывать большое количество данных для каждой записи?[/quote]

Чтоб обработать большое количество даннных, best practice это исползование Batch Apex.
Default batch size 200, максимум 2000 и можно исползовать Global переменные (List/Map).

Надеюсь что в будущем добавят Duplicate Management (Matching rule + Duplicate rule) в объект Case 

Idea:
https://success.salesforce.com/ideaView?id=08730000000DjN5AAK

AntonB
У меня вообще финальная цель такая, что мне надо вернуть все кейсы которые схожие с каким то одним, так скажем главным. Для того, чтобы понять схожие ли они у меня есть 7 полей, по которым я сравниваю.

У тебя достаточно сложный случай, который не решить одним запросом.
Если рассуждать теоретически тебе надо свести все 7 полей к какому-то одному значению которое хранить в отдельном поле, которое и использовать для поиска.
Если бы критерии сравнения (исходные данные для поиска по полям) были статичными, то можно было бы сделать Formula Field в котором прописать сравнение по полям и возвращение некого процента совпадения. Тогда бы можно было в SOQL добавить
WHERE my_formula_field >= :90
Но я так понимаю что исходным у тебя может быть ЛЮБОЙ кейс и следовательно значения для сравнения нельзя захардкодить.
Еще вариант с батчем:
- запилить отдельно таблицу где хранить что-то похожее на Case_1_ID, Case_2_ID, number_of_equals_fiels
- запускать периодически батч который будет заполнять эту таблицу.
Или делать тоже самое что в батче но через future метод который запускать из триггера для отдельного case.

Интересная задача. Хоть голову можно поломать

[quote="AntonB"]У меня вообще финальная цель такая, что мне надо вернуть все кейсы которые схожие с каким то одним, так скажем главным. Для того, чтобы понять схожие ли они у меня есть 7 полей, по которым я сравниваю. [/quote]
У тебя достаточно сложный случай, который не решить одним запросом. 
Если рассуждать теоретически тебе надо свести все 7 полей к какому-то одному значению которое хранить в отдельном поле, которое и использовать для поиска.
Если бы критерии сравнения (исходные данные для поиска по полям) были статичными, то можно было бы сделать Formula Field в котором прописать сравнение по полям и возвращение некого процента совпадения. Тогда бы можно было в SOQL добавить 
WHERE my_formula_field >= :90
Но я так понимаю что исходным у тебя может быть ЛЮБОЙ кейс и следовательно значения для сравнения нельзя захардкодить. 
Еще вариант с батчем: 
- запилить отдельно таблицу где хранить что-то похожее на Case_1_ID, Case_2_ID, number_of_equals_fiels
- запускать периодически батч который будет заполнять эту таблицу.
Или делать тоже самое что в батче но через future метод который запускать из триггера для отдельного case.

Интересная задача. Хоть голову можно поломать :) 

Попробуй может проанализировать вот этот случай
https://stackoverflow.com/questions/2108187/sql-find-rows-and-sort-according-to-number-of-matching-columns
Он конечно для обычных SQL баз данных, но может его можно переделать на SOQL запрос. Пока у самого нет времени в нем копаться :(

Попробуй может проанализировать вот этот случай
https://stackoverflow.com/questions/2108187/sql-find-rows-and-sort-according-to-number-of-matching-columns
Он конечно для обычных SQL баз данных, но может его можно переделать на SOQL запрос. Пока у самого нет времени в нем копаться :(

AntonB
Dmitry Shnyrev
Если бы ты был на месте базы данных чтобы ты ответил на эту просьбу?

Ну да, получается, что вернет все где или одно или все из этих условий соблюдаются.

Dmitry Shnyrev
Я бы делал по простому в лоб. Сначала выбрал все записи где все поля совпадают. Если их меньше 100 вернулось, то запросил бы записи где совпадают 2 поля в различных комбинациях. Если первый и второй запрос в сумме вернули меньше 100, то уже применил бы твой запрос выше.

У меня вообще финальная цель такая, что мне надо вернуть все кейсы которые схожие с каким то одним, так скажем главным. Для того, чтобы понять схожие ли они у меня есть 7 полей, по которым я сравниваю. То как я делаю сейчас, это пишу запрос со всеми полями через OR, потом прогоняю их через цикл и считаю количество полей которые совпали с значением в поле главного кейса. В результате, у меня получается Map<Id, Integer> где я храню id похожего кейса и количество полей одинаковых с главным кейсом.
Проблема в том, что запрос в котором все поля через OR возвращает около 20к записей. И потом после этого еще кучу других вычислений и запросов надо делать по этому для некоторых кейсов бьет по cpu limit.

Какие есть вообще практики, в случае когда нужно обрабатывать большое количество данных для каждой записи? Я попытался сделать batch которая будет работать для каждой записи отдельно, но как я понимаю, это не самая лучшая практика.


Лучший вариант по соотношению затрата усилий/результат будет батч. Лучше всего не вызывать его из триггера, а брать записи за определенный период(например, последний час) и там уже считать все что нужно. Частые батчи(раз в минуту-две-пять) тоже можно, но там свои проблемы потенциальные могут быть - если будешь ранить каждую минуту и брать кейсы за последнюю минуту - есть большая вероятность, что твой батч исполнится не сразу, а через 5 минут и исправно возьмет кейсы за последнюю минуту, пропустив при этом кейсы за последние 4 минуты.

[quote="AntonB"][quote="Dmitry Shnyrev"]
Если бы ты был на месте базы данных чтобы ты ответил на эту просьбу?
[/quote] 
Ну да, получается, что вернет все где или одно или все из этих условий соблюдаются. 

[quote="Dmitry Shnyrev"]Я бы делал по простому в лоб. Сначала выбрал все записи где все поля совпадают. Если их меньше 100 вернулось, то запросил бы записи где совпадают 2 поля в различных комбинациях. Если первый и второй запрос в сумме вернули меньше 100, то уже применил бы твой запрос выше.[/quote]

У меня вообще финальная цель такая, что мне надо вернуть все кейсы которые схожие с каким то одним, так скажем главным. Для того, чтобы понять схожие ли они у меня есть 7 полей, по которым я сравниваю. То как я делаю сейчас, это пишу запрос со всеми полями через OR, потом прогоняю их через цикл и считаю количество полей которые совпали с значением в поле главного кейса. В результате, у меня получается Map<Id, Integer> где я храню id похожего кейса и количество полей одинаковых с главным кейсом. 
Проблема в том, что запрос в котором все поля через  OR возвращает около 20к записей. И потом после этого еще кучу других вычислений и запросов надо делать по этому для некоторых кейсов бьет по cpu limit.

Какие есть вообще практики, в случае когда нужно обрабатывать большое количество данных для каждой записи? Я попытался сделать batch которая будет работать для каждой записи отдельно, но как я понимаю, это не самая лучшая практика.[/quote]
Лучший вариант по соотношению затрата усилий/результат будет батч. Лучше всего не вызывать его из триггера, а брать записи за определенный период(например, последний час) и там уже считать все что нужно. Частые батчи(раз в минуту-две-пять) тоже можно, но там свои проблемы потенциальные могут быть - если будешь ранить каждую минуту и брать кейсы за последнюю минуту - есть большая вероятность, что твой батч исполнится не сразу, а через 5 минут и исправно возьмет кейсы за последнюю минуту, пропустив при этом кейсы за последние 4 минуты. 

Допустим у нас есть сем условий A, B, C, D, E, F и G. Есть два возможных варианта решения задачи:
1. Если надо получить все данные - не обойтись без условия A or B or C or D or E or F or G, обработки всех записей и соответсвенно решения проблемы с большим кол-вом записей, где самый очевидный способ решения - отправить всё в батч.
2. Если надо получить первые N записей максимально близкие к исходному Case, т.е. удовлетворяющие максимальному кол-ву условий, тогда можно переложить работу на сторону базы и поочередно выполнять кучу запросов от самых строгих до более расслабленных: сначала все семь A and B and C and D and E and F and G, потом все комбинации из шести условий, и т.д. В худшем случае таких запросов будет 2^7 = 128, что в принципе терпимо и решаемо, но можно пытаться запихнуть как можно больше комбинаций одного уровня в запрос, например для двоек ((A and B) or (A and C) or (A and D) or (A and E) or (A and F) or (A and G) or (B and C) or (B and D)...) - такой оптимизацией можно попробовать уложиться в сотню SOQL запросов.

Допустим у нас есть сем условий A, B, C, D, E, F и G. Есть два возможных варианта решения задачи:
1. Если надо получить все данные - не обойтись без условия A or B or C or D or E or F or G, обработки всех записей и соответсвенно решения проблемы с большим кол-вом записей, где самый очевидный способ решения - отправить всё в батч.
2. Если надо получить первые N записей максимально близкие к исходному Case, т.е. удовлетворяющие максимальному кол-ву условий, тогда можно переложить работу на сторону базы и поочередно выполнять кучу запросов от самых строгих до более расслабленных: сначала все семь A and B and C and D and E and F and G, потом все комбинации из шести условий, и т.д. В худшем случае таких запросов будет 2^7 = 128, что в принципе терпимо и решаемо, но можно пытаться запихнуть как можно больше комбинаций одного уровня в запрос, например для двоек ((A and B) or (A and C) or (A and D) or (A and E) or (A and F) or (A and G) or (B and C) or (B and D)...) - такой оптимизацией можно попробовать уложиться в сотню SOQL запросов.

ilya leshchuk
2. Если надо получить первые N записей максимально близкие к исходному Case, т.е. удовлетворяющие максимальному кол-ву условий, тогда можно переложить работу на сторону базы и поочередно выполнять кучу запросов от самых строгих до более расслабленных: сначала все семь A and B and C and D and E and F and G, потом все комбинации из шести условий, и т.д. В худшем случае таких запросов будет 2^7 = 128, что в принципе терпимо и решаемо, но можно пытаться запихнуть как можно больше комбинаций одного уровня в запрос, например для двоек ((A and B) or (A and C) or (A and D) or (A and E) or (A and F) or (A and G) or (B and C) or (B and D)...) - такой оптимизацией можно попробовать уложиться в сотню SOQL запросов.

Хороший вариант, я думаю, так и попытаюсь сделать, спасибо!

EvAzi
Лучший вариант по соотношению затрата усилий/результат будет батч. Лучше всего не вызывать его из триггера, а брать записи за определенный период(например, последний час) и там уже считать все что нужно

Да, я пробовал из триггера, но не очень хорошо выходит, потому, что только 5 батчей можно иметь одновременно работающих, если не ошибаюсь.

Я думаю, попробовать запихнуть в контроллер к компоненту. В конце концов, у меня должен выйти список контактов как результат, которые когда то решали похожие кейс, то есть, это что то на подобие страницы с рекомендациями кто может решить этот кейс. Я думал использовать батч, чтоб эти значения были уже посчитаны до того как юзер открывает страницу, но думаю если сделать более жесткие условия и лимиты для запроса чтоб возвращать меньше записей, то попробовать делать сразу на странице. Чревато ли это какими нибудь еще последствиями, кроме как страницы которая будет открываться около 3-5 секунд?

И еще один вопрос, но тоже достаточно общий. А как Salesforce работает в плане загруженности системы, например в понедельник утром, когда предположим системой будет пользоваться наибольшее количество юзеров в орге, урезает ли в таком случае salesforce как нибудь производительность и увеличивается ли время запросов? Есть ли какая нибудь статистика по этому поводу или цифры?

[quote="ilya leshchuk"]
2. Если надо получить первые N записей максимально близкие к исходному Case, т.е. удовлетворяющие максимальному кол-ву условий, тогда можно переложить работу на сторону базы и поочередно выполнять кучу запросов от самых строгих до более расслабленных: сначала все семь A and B and C and D and E and F and G, потом все комбинации из шести условий, и т.д. В худшем случае таких запросов будет 2^7 = 128, что в принципе терпимо и решаемо, но можно пытаться запихнуть как можно больше комбинаций одного уровня в запрос, например для двоек ((A and B) or (A and C) or (A and D) or (A and E) or (A and F) or (A and G) or (B and C) or (B and D)...) - такой оптимизацией можно попробовать уложиться в сотню SOQL запросов.[/quote]

Хороший вариант, я думаю, так и попытаюсь сделать, спасибо!

[quote="EvAzi"]
Лучший вариант по соотношению затрата усилий/результат будет батч. Лучше всего не вызывать его из триггера, а брать записи за определенный период(например, последний час) и там уже считать все что нужно[/quote] 

Да, я пробовал из триггера, но не очень хорошо выходит, потому, что только 5 батчей можно иметь одновременно работающих, если не ошибаюсь.

Я думаю, попробовать запихнуть в контроллер к компоненту. В конце концов, у меня должен выйти список контактов как результат, которые когда то решали похожие кейс, то есть, это что то на подобие страницы с рекомендациями кто может решить этот кейс. Я думал использовать батч, чтоб эти значения были уже посчитаны до того как юзер открывает страницу, но думаю если сделать более жесткие условия и лимиты для запроса чтоб возвращать меньше записей, то попробовать делать сразу на странице. Чревато ли это какими нибудь еще последствиями, кроме как страницы которая будет открываться около 3-5 секунд? 

И еще один вопрос, но тоже достаточно общий. А как Salesforce работает в плане загруженности системы, например в понедельник утром, когда предположим системой будет пользоваться наибольшее количество юзеров в орге, урезает ли в таком случае salesforce как нибудь производительность и увеличивается ли время запросов? Есть ли какая нибудь статистика по этому поводу или цифры? 


Dmitry Shnyrev
- запилить отдельно таблицу где хранить что-то похожее на Case_1_ID, Case_2_ID, number_of_equals_fiels
- запускать периодически батч который будет заполнять эту таблицу.

Я попытался сохранять в таблицу уже финальный результат, который мне в конце нужно показывать, но тогда когда запускал батч для каждой записи, то много где бил по cpu лимиту.

И опять всплывает достаточно общий вопрос, что делает salesforce в плане производительности когда запускается большая батч для многих записей? Я просто наблюдал, когда я запускаю батч для одной записи то это занимает n количество времени, но когда точно такая же батч для такой же записи стоит в очереди и потом выполняется то это может занимать 20n времени. Почему так и как это работает, может ли кто нибудь объяснить?

[quote="Dmitry Shnyrev"]
- запилить отдельно таблицу где хранить что-то похожее на Case_1_ID, Case_2_ID, number_of_equals_fiels
- запускать периодически батч который будет заполнять эту таблицу.
[/quote]

Я попытался сохранять в таблицу уже финальный результат, который мне в конце нужно показывать, но тогда когда запускал батч для каждой записи, то много где бил по cpu лимиту. 

И опять всплывает достаточно общий вопрос, что делает salesforce в плане производительности когда запускается большая батч для многих записей? Я просто наблюдал, когда я запускаю батч для одной записи то это занимает n количество времени, но когда точно такая же батч для такой же записи стоит в очереди и потом выполняется то это может занимать 20n времени. Почему так и как это работает, может ли кто нибудь объяснить? 

AntonB
Я думаю, попробовать запихнуть в контроллер к компоненту.

С этого и надо было начинать - если это страница, так можно ж гонять кучу запросов туда сюда и не упираться в лимиты, т.е. например сделать семь запросов - первый на получение Case'ов удовлетворяющих всем семи условиям, второй - шести за вычетом уже полученных, и т.д. и подгружать данные постепенно.

AntonB
И опять всплывает достаточно общий вопрос, что делает salesforce в плане производительности когда запускается большая батч для многих записей?

Если не изменяет память - да, скорость может проседать в зависимости от нагруженности системы, которая может зависеть и от дня недели, о чём SF открыто говорит заявляя что обрабатывается всё по мере появления свободных ресурсов, так что в самом худшем варианте батч может залипнуть на приличное кол-во времени, плюс там ещё влияет тип батча - stateful могут быть в целом медленнее из-за расходов на сериализацию/десериализацию состояния.

[quote="AntonB"]Я думаю, попробовать запихнуть в контроллер к компоненту.[/quote]
С этого и надо было начинать - если это страница, так можно ж гонять кучу запросов туда сюда и не упираться в лимиты, т.е. например сделать семь запросов - первый на получение Case'ов удовлетворяющих всем семи условиям, второй - шести за вычетом уже полученных, и т.д. и подгружать данные постепенно.

[quote="AntonB"]И опять всплывает достаточно общий вопрос, что делает salesforce в плане производительности когда запускается большая батч для многих записей?[/quote]
Если не изменяет память - да, скорость может проседать в зависимости от нагруженности системы, которая может зависеть и от дня недели, о чём SF открыто говорит заявляя что обрабатывается всё по мере появления свободных ресурсов, так что в самом худшем варианте батч может залипнуть на приличное кол-во времени, плюс там ещё влияет тип батча - stateful могут быть в целом медленнее из-за расходов на сериализацию/десериализацию состояния.

AntonB
И опять всплывает достаточно общий вопрос, что делает salesforce в плане производительности когда запускается большая батч для многих записей?

Официально SLA батча 24 часов.
~99% батч начинает бежать в течении несколько минут, ~1% может взять намного больше.
Зависит от загружености Data Center, (NA8, EU1...) так как очередь асинхронных процессов общая

[quote="AntonB"]И опять всплывает достаточно общий вопрос, что делает salesforce в плане производительности когда запускается большая батч для многих записей?[/quote]

Официально SLA батча 24 часов.
~99% батч начинает бежать в течении несколько минут, ~1% может взять намного больше.
Зависит от загружености Data Center, (NA8, EU1...) так как очередь асинхронных процессов общая

Рассказываю как в итоге решил задачу.

Сначала попробовал кверить все нужные записи просто через or и потом их как то фильтровать, но работало достаточно медленно из за объема данных и из за вычислений который нужно было делать с ними после.

Потом решил по очереди вызывать запросы от самого строгого к менее строгим, то есть сначала где все поля через and, потом все запросы со всеми комбинациями где 5 полей из 6 заполнены, и так далее.

Сначала попробовал просто написать все запросы вручную, что выглядело не очень красиво.
Потом пришел коллега и сказал, что я делаю ерунду и помог написать функцию которая будет находить все возможные комбинации k элементов из n. Вот с этим алгоритмом https://stackoverflow.com/questions/127704/algorithm-to-return-all-combinations-of-k-elements-from-n#127856 . Не думаю, что в Apex это слишком часто используется, но вышел рекурсивный метод, который дает все возможные комбинации по типу из a,b,c,d,e дает (a, b, c) or (a, b, d) or (a, b, e) or(c, b, e)

В итоге я делаю один большой запрос, для каждого из случаев по строгости условия. И генерирую динамическую soql query с помощью этой функции.

Рассказываю как в итоге решил задачу. 

Сначала попробовал кверить все нужные записи просто через or  и потом их как то фильтровать, но работало достаточно медленно из за объема данных и из за вычислений который нужно было делать с ними после.

Потом решил по очереди вызывать запросы от самого строгого к менее строгим, то есть сначала где все поля через and, потом все запросы со всеми комбинациями где 5 полей из 6 заполнены, и так далее. 

Сначала попробовал просто написать все запросы вручную, что выглядело не очень красиво. 
Потом пришел коллега и сказал, что я делаю ерунду и помог написать функцию которая будет находить все возможные комбинации k элементов из n. Вот с этим алгоритмом https://stackoverflow.com/questions/127704/algorithm-to-return-all-combinations-of-k-elements-from-n#127856 . Не думаю, что в Apex это слишком часто используется, но вышел рекурсивный метод, который дает все возможные комбинации по типу из a,b,c,d,e дает (a, b, c) or (a, b, d) or (a, b, e) or(c, b, e)

В итоге я делаю один большой запрос, для каждого из случаев по строгости условия. И генерирую динамическую soql query с помощью этой функции.

Вот это правильно! Спасибо что поделился результатами.

Вот это правильно! Спасибо что поделился результатами.