#amazon-web-services #amazon-redshift
Вопрос:
У меня есть следующий запрос к RedShift:
SELECT contributor_user_id,
device_id_source,
device_os,
device_model,
device_design,
device_serial,
device_carrier,
device_os_version,
device_manufacturer,
device_current_app_build,
device_current_app_version
FROM all_values
WHERE all_values.device_id_source :: VARCHAR NOT IN (SELECT device_id_source FROM table WHERE device_id_source IS NOT NULL)
AND all_values.device_os :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_os IS NOT NULL)
AND all_values.device_model :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_model IS NOT NULL)
AND all_values.device_design :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_design IS NOT NULL)
AND all_values.device_serial :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_serial IS NOT NULL)
AND all_values.device_carrier :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_carrier IS NOT NULL)
AND all_values.device_os_version :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_os_version IS NOT NULL)
AND all_values.device_manufacturer :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_manufacturer IS NOT NULL)
AND all_values.device_current_app_build :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_current_app_build IS NOT NULL)
AND all_values.device_current_app_version :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_current_app_version IS NOT NULL)
)
Как я знаю, ГДЕ В (ВЫБРАТЬ) работает медленнее, чем «ПРИСОЕДИНИТЬСЯ», и в подзапросе много одинаковых запросов, и я думаю, что это нехорошо. Но я новичок в SQL и не знаю, как переписать приведенный выше код с помощью JOIN. Не могли бы вы помочь мне со знаниями?
Тнхх!
Комментарии:
1. Всегда ли таблицы в подзапросах являются одной и той же таблицей?
2. Да, «таблица» во всех подзапросах одинакова
Ответ №1:
«ГДЕ НЕТ (ВЫБЕРИТЕ …» может быть очень дорогим, так как список может быть очень длинным и потребуется много сравнений, чтобы определить, нет ли значения в списке. Несколько менее дорогостоящий способ сделать это-использовать «ГДЕ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ…», что больше похоже на внутреннюю структуру СОЕДИНЕНИЯ, но все же может быть недостаточно быстрым для вашего случая.
Обратите внимание, что это всего лишь догадки, основанные на вашем SQL и прошлом опыте. Учитывая, насколько просто выглядит остальная часть запроса, это хорошая ставка. Возможно, вам все же захочется взглянуть на план ОБЪЯСНЕНИЯ запроса и посмотреть, где стоимость увеличивается больше всего.
Лучший ответ-переосмыслить этот запрос и удалить негативную логику. Если я правильно читаю, вы хотите найти все строки в contributor_user_id, где соответствующее значение столбца в «таблице» для ЛЮБОГО из перечисленных столбцов равно НУЛЮ. Для этого вы выполняете алгоритм вычитания, используя «ГДЕ НЕ В». Я не знаю вашу модель данных, поэтому не уверен, что эта логика неверна.
Трудность здесь в том, что я не знаю ваших данных и модели данных. Запрос отметит любую строку, в которой любой столбец равен нулю в «таблице», но только в том случае, если в «таблице»нет повторений device_os. Например, одна строка в «таблице» с нулем для device_model, но не является нулем для device_design в другой строке и имеет то же значение device_os, не будет отмечена. Все зависит от того, какие юридические шаблоны содержатся в ваших данных. Допустимы ли в ваших данных несколько строк с одним и тем же device_os?
Лучший способ-превратить это в аддитивный алгоритм, который может значительно сократить работу, необходимую для получения желаемого ответа. Не понимая данных и желаемой логики, я не могу предложить решение. Примеры данных и ожидаемые результаты помогут сделать другое предложение по решению.