Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
Делали тут небольшое сравнение СУБД и нарвались на вот какую проблему:

Запрос:

SELECT COUNT(*) FROM ShipmentDetail s1, ShipmentDetail s2 WHERE s1.sd=s2.sd AND s1.id <> s2.id


План запроса:
Rows	Executes  Stmt Text
1	1	  |--Compute Scalar(DEFINE:([Expr1002]=CONVERT_IMPLICIT(int,[Expr1008],0)))
1	1	       |--Hash Match(Aggregate, HASH:() DEFINE:([Expr1008]=COUNT(*)))
0	1	            |--Nested Loops(Inner Join, OUTER REFERENCES:([s1].[id], [s1].[sd], [Expr1007]) WITH UNORDERED PREFETCH)
10000001	1	                 |--Index Scan(OBJECT:([test].[dbo].[shipmentdetail].[shipmentdetail_sd] AS [s1]))
0	10000001	                 |--Index Seek(OBJECT:([test].[dbo].[shipmentdetail].[shipmentdetail_sd] AS [s2]), SEEK:([s2].[sd]=[test].[dbo].[shipmentdetail].[sd] as [s1].[sd]),  WHERE:([test].[dbo].[shipmentdetail].[id] as [s1].[id]<>[test].[dbo].[shipmentdetail].[id] as [s2].[id]) ORDERED FORWARD)


То есть MS SQL не догадывается бежать только по не NULL значениям. При этом если добавить явно IS NOT NULL все становится хорошо. Там может нужен какой-то специальный тип индекса?

И странно что Oracle отлично разруливает эту проблему.
12 авг 19, 10:57    [21946882]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Cammomile
Member

Откуда:
Сообщений: 1212
А почему вы задокументированное поведение называете проблемой? Тут нет никакой проблемы.
12 авг 19, 11:05    [21946901]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
Cammomile
А почему вы задокументированное поведение называете проблемой? Тут нет никакой проблемы.


Ну так запрос выполняется 3 секунды. А у Oracle 30мс.
12 авг 19, 11:33    [21946942]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Konst_One
Member

Откуда:
Сообщений: 11429
oracle != mssql - запомните и дальше станет проще
12 авг 19, 11:45    [21946967]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
Konst_One
oracle != mssql - запомните и дальше станет проще


Поверьте я это заметил. Я бы даже сказал это два антипода.

Причем, как человеку с навязчивым перфекционизмом, я очень благодарен Oracle. Потому как когда ты делаешь говно и тебя это напрягает, ты вспоминаешь что есть такая штука как Oracle и тебе становится гораздо легче.

Я когда тестировал три базы, и мне надо было что-то проверить на Oracle я понимал, что а) логику надо выключить, б) приготовиться долбаться с ним в раза 4 больше чем с остальными.
12 авг 19, 11:58    [21946989]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
andy st
Member

Откуда:
Сообщений: 741
Nitro_Junkie,
в статье ребята не смогли в SQL, поэтому придумали какую-то свою приблуду и попытались написать, почему в SQL всё плохо.
Те же cross apply и instead of триггеры для вьюшек как-то упустили.
Может не знали - подтверждение что "не смогли в SQL". Если знали и не описали, ибо в статью слегка ломало - то что-то другое :)
12 авг 19, 12:04    [21946994]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Konst_One
Member

Откуда:
Сообщений: 11429
Курсоры, триггеры и развесистый pl/sql - это часто встречающийся подход в оракле, который ломается, когда вы хотите сделать так же на mssql. И, аналогично, обычные подходы из mssql часто не самые эффективные в оракле.
12 авг 19, 12:12    [21947006]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
andy st
Nitro_Junkie,
в статье ребята не смогли в SQL, поэтому придумали какую-то свою приблуду и попытались написать, почему в SQL всё плохо.
Те же cross apply и instead of триггеры для вьюшек как-то упустили.
Может не знали - подтверждение что "не смогли в SQL". Если знали и не описали, ибо в статью слегка ломало - то что-то другое :)


С CROSS APPLY дополнили статью. INSTEAD OF это не то в данном случае. Если вы сделаете триггер INSTEAD OF на balance, он не будет вызываться, когда скажем shipmentDetail поменялось, а там именно об этом речь шла.
12 авг 19, 12:12    [21947007]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Konst_One
Member

Откуда:
Сообщений: 11429
вы в той статье сами себя загнали в угол с такой архитектурой данных, которая не очень удобна для работы в mssql, а потом пытаетесь героически преодолеть ограничения.
12 авг 19, 12:13    [21947008]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
Konst_One
Курсоры, триггеры и развесистый pl/sql - это часто встречающийся подход в оракле, который ломается, когда вы хотите сделать так же на mssql. И, аналогично, обычные подходы из mssql часто не самые эффективные в оракле.


Вот это странно, потому как триггеры в MS SQL имхо сделаны лучше чем в оракл. Во всяком случае там N+1 проблему победили. И многие ораклоиды поэтому мне говорили, что стараются избегать триггеров.
12 авг 19, 12:42    [21947045]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
Konst_One
вы в той статье сами себя загнали в угол с такой архитектурой данных, которая не очень удобна для работы в mssql, а потом пытаетесь героически преодолеть ограничения.


А что там такого особенного в архитектуре. Там же просто документы/ остатки и т.п. Или вы что-то другое имеете ввиду?
12 авг 19, 12:44    [21947051]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Konst_One
Member

Откуда:
Сообщений: 11429
имелось ввиду как вы эти данные храните (стуктуру таблиц и их взаимосвязь)
12 авг 19, 12:46    [21947052]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
andy st
Member

Откуда:
Сообщений: 741
Nitro_Junkie
andy st
Nitro_Junkie,
в статье ребята не смогли в SQL, поэтому придумали какую-то свою приблуду и попытались написать, почему в SQL всё плохо.
Те же cross apply и instead of триггеры для вьюшек как-то упустили.
Может не знали - подтверждение что "не смогли в SQL". Если знали и не описали, ибо в статью слегка ломало - то что-то другое :)


С CROSS APPLY дополнили статью. INSTEAD OF это не то в данном случае. Если вы сделаете триггер INSTEAD OF на balance, он не будет вызываться, когда скажем shipmentDetail поменялось, а там именно об этом речь шла.

ммм...
а давайте придумаем еще еще какие-нибудь свои правила и будем радоваться, что ни одна субд их не поддерживает.
12 авг 19, 13:12    [21947086]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
Konst_One
имелось ввиду как вы эти данные храните (стуктуру таблиц и их взаимосвязь)


А как если не секрет по вашему нужно было структуру таблиц в данном случае организовывать?
12 авг 19, 14:08    [21947165]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
andy st
Nitro_Junkie
пропущено...


С CROSS APPLY дополнили статью. INSTEAD OF это не то в данном случае. Если вы сделаете триггер INSTEAD OF на balance, он не будет вызываться, когда скажем shipmentDetail поменялось, а там именно об этом речь шла.

ммм...
а давайте придумаем еще еще какие-нибудь свои правила и будем радоваться, что ни одна субд их не поддерживает.


Что значит придумывать правила? Допустим вам надо логировать ситуации, когда количество остатка стало меньше 0. Вроде элементарная задача, как ее при помощи INSTEAD OF триггера реализовать?
12 авг 19, 14:10    [21947171]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
andy st
Member

Откуда:
Сообщений: 741
Nitro_Junkie
andy st
пропущено...

ммм...
а давайте придумаем еще еще какие-нибудь свои правила и будем радоваться, что ни одна субд их не поддерживает.


Что значит придумывать правила? Допустим вам надо логировать ситуации, когда количество остатка стало меньше 0. Вроде элементарная задача, как ее при помощи INSTEAD OF триггера реализовать?

а делать это на этапе добавления записи, которая может привести к остатку < 0, не?
или подразумевается, что кто-то может править содержимое вьюхи в плане изменения остатка? типа чёта мало тут, давай сотку накинем... тогда ребята правильно путём идут бизнес делать.
12 авг 19, 14:22    [21947184]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
andy st
Nitro_Junkie
пропущено...


Что значит придумывать правила? Допустим вам надо логировать ситуации, когда количество остатка стало меньше 0. Вроде элементарная задача, как ее при помощи INSTEAD OF триггера реализовать?

а делать это на этапе добавления записи, которая может привести к остатку < 0, не?
или подразумевается, что кто-то может править содержимое вьюхи в плане изменения остатка? типа чёта мало тут, давай сотку накинем... тогда ребята правильно путём идут бизнес делать.


Какой записи? Допустим у вас остаток расчитывается, как-то хитро.

Кто-то делает какое-то изменение UPDATE shipmentDetail SET product=54 WHERE id=123

Это для старого товара уменьшит остаток, для нового увеличит. То есть остаток может стать меньше 0, это хочется залогировать (для склада товара), вместе скажем с человеком и изменением которые привели к этому.

Если бы можно было сделать триггер на представление balance все делалось бы одной строчкой. А так вариантов которые приведут к тому что останет меньше 0 сотни. Куда что вставлять?
12 авг 19, 14:50    [21947210]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Konst_One
Member

Откуда:
Сообщений: 11429
остаток не должен расчитываться, он должен записываться
12 авг 19, 14:54    [21947215]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
invm
Member

Откуда: Москва
Сообщений: 8717
Nitro_Junkie
Если бы можно было сделать триггер на представление balance все делалось бы одной строчкой.
Ну так делайте. Или что-то мешает?
12 авг 19, 15:53    [21947296]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 6639
Nitro_Junkie,

SELECT COUNT(*) FROM ShipmentDetail s1, ShipmentDetail s2 WHERE s1.sd=s2.sd AND s1.id <> s2.id


Вы чего-то не договариваете. У меня план запроса на таблице с индексом по nullable колонке очень простой - constant scan. Скорее всего,выбран тривиальный план.

Версия сервера какая, интересно?
12 авг 19, 16:28    [21947348]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
Konst_One
остаток не должен расчитываться, он должен записываться


Ну для начала определяется как должен рассчитываться, а как записываться это уже следствие.
12 авг 19, 17:27    [21947412]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
invm
Nitro_Junkie
Если бы можно было сделать триггер на представление balance все делалось бы одной строчкой.
Ну так делайте. Или что-то мешает?

MS SQL не дает триггеры на представления делать.
12 авг 19, 17:28    [21947414]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Konst_One
Member

Откуда:
Сообщений: 11429
Nitro_Junkie
Konst_One
остаток не должен расчитываться, он должен записываться


Ну для начала определяется как должен рассчитываться, а как записываться это уже следствие.



не надо для этого делать представления, программа должна уже расчитанный остаток зхаписывать в отдельную таблицу
12 авг 19, 17:31    [21947417]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1011
Nitro_Junkie
invm
пропущено...
Ну так делайте. Или что-то мешает?

MS SQL не дает триггеры на представления делать.

А пацаны то не знали...

https://docs.microsoft.com/ru-ru/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-2017

CREATE [ OR ALTER ] TRIGGER [ schema_name . ]trigger_name
ON { table | view }
12 авг 19, 17:31    [21947418]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с оптимизацией IS NOT NULL  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1042
Владислав Колосов
Nitro_Junkie,

SELECT COUNT(*) FROM ShipmentDetail s1, ShipmentDetail s2 WHERE s1.sd=s2.sd AND s1.id <> s2.id


Вы чего-то не договариваете. У меня план запроса на таблице с индексом по nullable колонке очень простой - constant scan. Скорее всего,выбран тривиальный план.

Версия сервера какая, интересно?


Да в том то и проблема, что выбирается тривиальный план.

SQL Server (15.0.1700.37) это 2019 preview как я понимаю. Но на эту проблему мне на всех серверах жаловались.
12 авг 19, 17:31    [21947419]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить