Не существует неисчерпывающего поиска чего-то, чего там нет.
Вероятно, мы сможем значительно повысить производительность вашего запроса для случая, когда существует запись со значением null
(см. ниже), но как насчет того, когда это не так?Если вы планируете запускать этот запрос несколько раз, а ответ меняется каждый раз, вы должны знать (я не имею в виду, что это не так), что если ответ «нет», значений null
нетво всем фрейме данных ", тогда вам придется сканировать весь фрейм данных, чтобы узнать это, и быстрого способа сделать это не существует.Если вам часто нужна такая информация, а ответ может быть «нет», вам почти наверняка захочется сохранить эту информацию где-нибудь и обновлять ее всякий раз, когда вы вставляете запись, которая может иметь значения null
, проверяя толькоэта запись.
Не используйте count ().
count()
, вероятно, ухудшает ситуацию.
- В случае подсчета Spark использовал широкое преобразование и фактически применяет LocalLimit для каждого раздела и перетасовывает частичные результаты для выполнения GlobalLimit.
- В случае взятия Spark использовал узкое преобразование и оценивал LocalLimit только в первом разделе.
Другими словами, .limit(1).count()
означает вероятность для выбора одного примера из каждого раздела вашего набора данных, прежде чем выбрать один пример из этого списка примеров.Ваше намерение состоит в том, чтобы прервать работу, как только будет найден один пример, но, к сожалению, count()
не кажется достаточно умным, чтобы достичь этого самостоятельно.
Как и в этом же примере, выможно использовать take()
, first()
или head()
для достижения желаемого варианта использования. Это будет более эффективно ограничивать количество проверяемых разделов:
Если не требуется перемешивание (никаких объединений, объединений или сортировок), эти операции будут оптимизированы для проверкидостаточно разделов для выполнения операции - вероятно, гораздо меньшее подмножество общих разделов набора данных.
Обратите внимание, что count()
может быть более производительным в других случаях.Как справедливо указал другой вопрос SO ,
ни один не гарантирует лучшую производительность в целом.
Может быть большевы можете сделать.
В зависимости от вашего метода хранения и схемы, вы можете увеличить производительность вашего запроса.
- Поскольку вас даже не интересует значениеиз строки, выбранной в этом случае, вы можете бросить
select(F.lit(True))
между вашим isnull
и вашим take
.Это должно в теории уменьшить количество информации, которую должны передавать работники кластера.Это вряд ли имеет значение, если у вас есть только несколько столбцов простых типов, но если у вас сложные структуры данных, это может помочь и вряд ли повредит. - Если вы знаете, как ваши данные разбиты на разделы и вы знаете, какой раздел (ы) вас интересует или у вас есть очень хорошее предположение о том, какие разделы (если есть) могут содержать значения
null
, вам следует определенно фильтруйте ваш фрейм данных по этому разделу, чтобы ускорить ваш запрос.