Это перевод статьи (которой уже больше 10 лет к тому же), поэтому добавлять что-то сюда считаю неправильным. Но вы вполне можете сами сделать и опубликовать расширенную версию :)
Следующим шагом, видимо, будет выход на рынок с "межоператорным шлюзом"?
Вообще, "шина данных" для ЭДО кажется хорошей идеей, даже для не-холдингов, если она берёт на себя работу со множеством операторов, потому что держать зоопарк коннекторов - это и правда боль. И делигировать эту боль кому-то было бы очень приятно:)
Кажется, что к выводам неплохо было бы добавить и регулярные проверки целостности. Старый полный бэкап + цепочка бэкапов ЖТ (при своевременном обнаружении) могли бы полностью решить проблему в примере 4.
Truncate– это команда DDL, она используется для удаления всех строк из таблицы и освобождения пространства, содержащего таблицу. Его нельзя откатить назад.
Можно откатить в MS SQL, PostgreSQL и, наверняка, в подавляющем большинстве РСУБД. В каких именно нельзя?
Drop– это команда DDL, она удаляет полные данные вместе со структурой таблицы (в отличие от команды truncate, которая удаляет только строки). Все строки, индексы и привилегии таблиц также будут удалены.
А Drop можно откатить? А в каких СУБД? А есть СУБД, где можно откатить Drop, но нельзя Truncate? Почему-то не указано...
А почему в обзоре pg_trgm индексов нигде не написано, что и обычные like/ilike он очень даже весомо ускоряет? Я практически уверен, что в 99% случаев их используют именно для ускорения запросов с like/ilke.
И в контексте использования для ускорения с like'ми было бы интересно узнать про выбор типа индекса gin/gist - в каком случае какой больше подходит.
Я сейчас ещё и на скриншоте пытался разницу найти (в тесте тоже не угадал), и понял, что оба синтаксически некорректные - в таблицах и cte remains_id, в условиях соединения - remainsid
TRUNCATE – это крайне простая и быстрая операция, по ней нельзя сделать rollback или наложить условия по столбцам. А потому, она выполняется мгновенно.
Какая интересная информация про ролбэк. Т.е. получается, что в результате выполнения этого:
create table #t1 (id int);
insert into #t1 (id) values (1);
select * from #t1;
begin tran;
truncate table #t1;
rollback tran;
select * from #t1;
я ну никак не мог получить это:
?
Что касается "простой" операции - нужно уточнять, что это "простая" DDL-операция, которая накладывает SCH-M блокировку (которая не совместима ни с одной другой, даже SCH-S, которую накладывают запросы с NOLOCK-хинтом) на всё время выполнения, что приводит к тому, что ни одна другая сессия не может обратиться к таблице, пока операция не завершится. В случае локальных временных таблиц - это не беда, но вы ведь и не только про них пишете.
Не включено ли у вас (ваших клиентов) MEMORY_OPTIMIZED TEMPDB_METADATA?
в общем случае, да, прироста производительности от разделения не замечу, но речь шла о том, что бывают ситуации, когда эта техника допустима и может быть полезна
что касается заметности влияния индексов, испытываю жгучее желание тоже броситься в частности и потыкать в очевидно медленные вещи типа gin в pg, но в общем случае, при разумном подходе к индексированию - спорить не буду
ну и я видел красивую таблицу со 170 столбцами и 90 индексами (не в хранилище) - это относительно того, что я увижу, или не увижу
окей, есть ещё два частных случая (хотя на счёт row overflow у меня нет твёрдой уверенности, что это справедливо для всех случаев), когда при использовании списка столбцов в память поднимутся не все поля
в общем случае же, в контексте предмета обсуждения, речь о том, что может иметь смысл выносить что-то в отдельную таблицу со связью 1-1, в т.ч. для экономии памяти
Сравнение значений. Если в таблице присутствуют значения NULL, то при выполнении операции сравнения, например, WHERE column_name = NULL, результатом будет False. Вместо этого нужно использовать оператор IS NULL.
Это ("результатом будет False") неправда. результатом будет Unknown, который и не True, и не False. Если бы результатом был False, то условие вида where not (colum_name = null) возвращало бы всё, где column_name не-null, а это так не работает.
Estimate'ы - это ни о чём. Вы же видите, что количество чтений из родного индекса стало даже меньше, чем из ручного на прошлом скрине (ему, видимо, тоже нужен ребилд, т.к. из него читать всё равно должно быть меньше).
Плюс, вы в запросе используете локальную переменную, что тоже может оказывать влияние на estimate, попробуйте этот запрос выполнить через sp_executesql
Новый индекс уже существующего, читать меньше. Условие на равенство бессмысленно, он это знает из статистики. Поле есть в индексе - видимо оно в составе ключа кластерного индекса (или вы включили его в included).
Фрагментация может влиять на план запроса - у Пола Вайта был пример, где при сильно фрагментировааном индексе выбирался параллельный план. Но я и правда не уверен, что она может влиять на выбор индекса.
Проверьте, кстати, fill factor у обоих индексов, если он ниже у родного индекса - это тоже будет влияние на разницу в чтении.
т.е. выражение вида where not (smth = null) даст true (будет истинным)?
Это перевод статьи (которой уже больше 10 лет к тому же), поэтому добавлять что-то сюда считаю неправильным. Но вы вполне можете сами сделать и опубликовать расширенную версию :)
Следующим шагом, видимо, будет выход на рынок с "межоператорным шлюзом"?
Вообще, "шина данных" для ЭДО кажется хорошей идеей, даже для не-холдингов, если она берёт на себя работу со множеством операторов, потому что держать зоопарк коннекторов - это и правда боль. И делигировать эту боль кому-то было бы очень приятно:)
Спасибо за пост.
Кажется, что к выводам неплохо было бы добавить и регулярные проверки целостности. Старый полный бэкап + цепочка бэкапов ЖТ (при своевременном обнаружении) могли бы полностью решить проблему в примере 4.
Можно откатить в MS SQL, PostgreSQL и, наверняка, в подавляющем большинстве РСУБД. В каких именно нельзя?
А Drop можно откатить? А в каких СУБД? А есть СУБД, где можно откатить Drop, но нельзя Truncate? Почему-то не указано...
А почему в обзоре pg_trgm индексов нигде не написано, что и обычные like/ilike он очень даже весомо ускоряет? Я практически уверен, что в 99% случаев их используют именно для ускорения запросов с like/ilke.
И в контексте использования для ускорения с like'ми было бы интересно узнать про выбор типа индекса gin/gist - в каком случае какой больше подходит.
На скрине в моём комментарии видно, что distinct там не было
345? RLY?
Я сейчас ещё и на скриншоте пытался разницу найти (в тесте тоже не угадал), и понял, что оба синтаксически некорректные - в таблицах и cte remains_id, в условиях соединения - remainsid
Нужна пояснительная бригада
В какой СУБД ответ, который считается правильным, вернётся приведённым запросом?
Какая интересная информация про ролбэк. Т.е. получается, что в результате выполнения этого:
я ну никак не мог получить это:
?
Что касается "простой" операции - нужно уточнять, что это "простая" DDL-операция, которая накладывает SCH-M блокировку (которая не совместима ни с одной другой, даже SCH-S, которую накладывают запросы с NOLOCK-хинтом) на всё время выполнения, что приводит к тому, что ни одна другая сессия не может обратиться к таблице, пока операция не завершится. В случае локальных временных таблиц - это не беда, но вы ведь и не только про них пишете.
Не включено ли у вас (ваших клиентов) MEMORY_OPTIMIZED TEMPDB_METADATA?
в общем случае, да, прироста производительности от разделения не замечу, но речь шла о том, что бывают ситуации, когда эта техника допустима и может быть полезна
что касается заметности влияния индексов, испытываю жгучее желание тоже броситься в частности и потыкать в очевидно медленные вещи типа gin в pg, но в общем случае, при разумном подходе к индексированию - спорить не буду
ну и я видел красивую таблицу со 170 столбцами и 90 индексами (не в хранилище) - это относительно того, что я увижу, или не увижу
прикол в том, что вы сами выдумали тейк про каждый столбец-таблица и сами его осудили
индексы на каждый чих тоже не бесплатное удовольствие
окей, есть ещё два частных случая (хотя на счёт row overflow у меня нет твёрдой уверенности, что это справедливо для всех случаев), когда при использовании списка столбцов в память поднимутся не все поля
в общем случае же, в контексте предмета обсуждения, речь о том, что может иметь смысл выносить что-то в отдельную таблицу со связью 1-1, в т.ч. для экономии памяти
если таблица не columnstore, с диска всё равно поднимутся все поля
Это ("результатом будет False") неправда. результатом будет Unknown, который и не True, и не False. Если бы результатом был False, то условие вида where not (colum_name = null) возвращало бы всё, где column_name не-null, а это так не работает.
ого
вы-то, да, огого, ага, сразу видно
Спасибо, многое ещё предстоит осмыслить, хотел уточнить вот что:
a'an зависит исключительно от произношения? Англоязычные, обычно, произносят SQL как "сиквел" - соответственно, подходит артикль 'a'. В доках оракла встречается, например, такое: A SQL script is a set of SQL commands saved as a file in SQL Scripts.
Оба варианта, получается, допустимы?
Estimate'ы - это ни о чём. Вы же видите, что количество чтений из родного индекса стало даже меньше, чем из ручного на прошлом скрине (ему, видимо, тоже нужен ребилд, т.к. из него читать всё равно должно быть меньше).
Плюс, вы в запросе используете локальную переменную, что тоже может оказывать влияние на estimate, попробуйте этот запрос выполнить через sp_executesql
Новый индекс уже существующего, читать меньше. Условие на равенство бессмысленно, он это знает из статистики. Поле есть в индексе - видимо оно в составе ключа кластерного индекса (или вы включили его в included).
Фрагментация может влиять на план запроса - у Пола Вайта был пример, где при сильно фрагментировааном индексе выбирался параллельный план. Но я и правда не уверен, что она может влиять на выбор индекса.
Проверьте, кстати, fill factor у обоих индексов, если он ниже у родного индекса - это тоже будет влияние на разницу в чтении.