Do not write expression = NULL because NULL is not “equal to” NULL. (The null value represents an unknown value, and it is not known whether two unknown values are equal.)
Note that if the left-hand expression yields null, or if there are no equal right-hand values and at least one right-hand expression yields null, the result of the NOT IN construct will be null, not true as one might naively expect. This is in accordance with SQL's normal rules for Boolean combinations of null values.
Tip
x NOT IN y is equivalent to NOT (x IN y) in all cases. However, null values are much more likely to trip up the novice when working with NOT IN than when working with IN. It is best to express your condition positively if possible.
IMHO, первое и единственное что должен был сделать сотрудник, это позвонить в Службу Безопасности - "Меня пытаются подкупить".
Каммент, скорее для тех, кто попадет в подобную ситуацию. Не надо играть в детектива, вести диалог с мошенниками, пытаться вывести на чистую воду. Сразу: звонок в СБ, дальше их работа.
Вот по части литературы сложно что-то посоветовать. Хороших современных книг по базам данных так сходу на ум не приходит.
Можно почитать старого доброго Тома Кайта. Книжка, конечно, старая, написана про Оракл, но базовые принципы всех РСУБД одинаковы и там объяснены. Читается легко, я бы даже сказал увлекательно.
Льюис Адамс... ну тяжеловатое чтиво, тем более что оптимизаторы с тех пор сильно продвинулись вперед. Но если есть цель немного "влезть под кожу" оптимайзера - то можно.
Совсем лайтовый вариант - курс QPT от PostgresPro, он свободно выложен у них на сайте. Толком ничего не объясняет, но "по вершкам", в принципе, пробегает.
Я не уверен, я знаю. :-) На самом деле всё еще хуже чем я писал.
я ему сразу указываю таблицу
Вот в этом и проблема.
Вам знакомы термины Hard Parse, Soft Parse, Library Cache ?
Вы в каждом запросе указываете СУБД разную таблицу, из-за чего ей приходится каждый раз делать hard parse и строить новый план.
На этапе hard-парсинга:
проверяется синтаксис запроса.
проверяется существование объектов запроса (select-ы к словарю)
проверяются права пользователя к этим объектам (select-ы к словарю)
проверяется наличие и тип колонок в таблицах (select-ы к словарю)
проверяются настройки безопасности любого уровня (select-ы к словарю)
На этапе построения плана запроса:
выбираются статистики по таблице (select-ы к словарю)
выбираются статистики по колонкам (select-ы к словарю)
выбираются наличие и состав индексов на таблицах (select-ы к словарю)
перебираются варианты доступа и соединения с оценкой стоимости
Это упрощенно, но надо ли вот это всё проделывать для каждого запроса? Или все-таки стоит не убивать СУБД, а проделать это один раз, а потом только переиспользовать проделанное и вызывать только фазу exec?
Достаточно один раз посмотреть трейс 10046 (это оракл), чтобы понять какую чудовищную работу приходится делать чтобы сделать hard parse.
Я ответил на ваш вопрос - "все говорят что не надо так делать, но не могут объяснить почему" ?
"Для человека, не изучавшего в школе физику, мир полон чудес" ;-)
Документация:
https://www.postgresql.org/docs/17/functions-comparisons.html
9.2. Comparison Functions and Operators
Do not write
expression
= NULL
becauseNULL
is not “equal to”NULL
. (The null value represents an unknown value, and it is not known whether two unknown values are equal.)https://www.postgresql.org/docs/17/functions-comparisons.html
9.25.2.
NOT IN
Note that if the left-hand expression yields null, or if there are no equal right-hand values and at least one right-hand expression yields null, the result of the
NOT IN
construct will be null, not true as one might naively expect. This is in accordance with SQL's normal rules for Boolean combinations of null values.Tip
x NOT IN y
is equivalent toNOT (x IN y)
in all cases. However, null values are much more likely to trip up the novice when working withNOT IN
than when working withIN
. It is best to express your condition positively if possible.IMHO, первое и единственное что должен был сделать сотрудник, это позвонить в Службу Безопасности - "Меня пытаются подкупить".
Каммент, скорее для тех, кто попадет в подобную ситуацию. Не надо играть в детектива, вести диалог с мошенниками, пытаться вывести на чистую воду. Сразу: звонок в СБ, дальше их работа.
>Он распознал, что предложенный «официальный бот» @TradeRequestBot для получения оплаты не имеет необходимой верификации
То есть, если бы бот был верифицированным, то он продал бы учетку?
Вентиляторы на процессоре? ;-)
Ап! ;-)
https://habr.com/ru/companies/jetinfosystems/articles/523326/
Вот по части литературы сложно что-то посоветовать. Хороших современных книг по базам данных так сходу на ум не приходит.
Можно почитать старого доброго Тома Кайта. Книжка, конечно, старая, написана про Оракл, но базовые принципы всех РСУБД одинаковы и там объяснены. Читается легко, я бы даже сказал увлекательно.
Льюис Адамс... ну тяжеловатое чтиво, тем более что оптимизаторы с тех пор сильно продвинулись вперед. Но если есть цель немного "влезть под кожу" оптимайзера - то можно.
Совсем лайтовый вариант - курс QPT от PostgresPro, он свободно выложен у них на сайте. Толком ничего не объясняет, но "по вершкам", в принципе, пробегает.
Добавлю, если это не очевидно.
Нормальная СУБД закэширует все этапы подготовки к исполнению в Library Cache и сама будет переиспользовать результаты парсинга и планирования.
Только не надо ей мешать и каждый раз подсовывать разные таблицы.
Я не уверен, я знаю. :-) На самом деле всё еще хуже чем я писал.
Вот в этом и проблема.
Вам знакомы термины Hard Parse, Soft Parse, Library Cache ?
Вы в каждом запросе указываете СУБД разную таблицу, из-за чего ей приходится каждый раз делать hard parse и строить новый план.
На этапе hard-парсинга:
проверяется синтаксис запроса.
проверяется существование объектов запроса (select-ы к словарю)
проверяются права пользователя к этим объектам (select-ы к словарю)
проверяется наличие и тип колонок в таблицах (select-ы к словарю)
проверяются настройки безопасности любого уровня (select-ы к словарю)
На этапе построения плана запроса:
выбираются статистики по таблице (select-ы к словарю)
выбираются статистики по колонкам (select-ы к словарю)
выбираются наличие и состав индексов на таблицах (select-ы к словарю)
перебираются варианты доступа и соединения с оценкой стоимости
Это упрощенно, но надо ли вот это всё проделывать для каждого запроса? Или все-таки стоит не убивать СУБД, а проделать это один раз, а потом только переиспользовать проделанное и вызывать только фазу exec?
Достаточно один раз посмотреть трейс 10046 (это оракл), чтобы понять какую чудовищную работу приходится делать чтобы сделать hard parse.
Я ответил на ваш вопрос - "все говорят что не надо так делать, но не могут объяснить почему" ?
Идея чудовищная.
Во-первых, это раздувание словаря, что не есть хорошо.
Во-вторых, на каждый запрос будут выполнятся все шаги Parse -> Rewrite -> Plan ->Execute.
И чем больше раздувается первое, тем медленнее работает оптимизатор (Plan) во втором.
Нормально - когда первые три фазы делаются один раз, а потом только выполняется Execute столько раз, сколько потребуется.