AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 16.03.2010, 15:26   #1  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Оптимизация запросов к БД в коде
----------------
sukhanchik Обсуждение вынесено из ветки Нужен совет: Oracle или MS SQL
----------------

5 лет назад я говорил, что "таких нет", кто будет выбирать в пользу MS SQL. Теперь я изменил свое мнение.
Работаю на базе данных MS SQL с 9 млн. проводок и 448 тыс. накладных. Никаких блокировок и тормозов нет. Все летает. Размер базы 150 ГБ.
Не парюсь со всякими хинтами типа forceplaceholders и forcenestedloops.
Везде использую exist join - очень удобно.

Чтобы база работала быстро, надо:
1) Большое количество памяти на сервере, чтобы информацию о блокировках записей SQL-сервер целиком помещал в памяти. Тогда не будет возникать страничных и табличных блокировок.
2) периодически перестраивать индексы и обновлять статистику запросов
3) программисту всегда проверять, есть ли индекс по полям, которые перечислены в выражении отбора "where". достаточно иметь индекс по первому полю, идущему в выражении отбора "where"
3)в выражении отбора "where" сначала перечислять более уникальные поля, а потом менее уникальные - например надо писать "where inventTrans.TransRefId == 'journalId' && inventTrans.TransType == InventTransType.InventTransfer". А так писать нельзя: "where inventTrans.TransType == InventTransType.InventTransfer && inventTrans.TransRefId == 'journalId' ".

Последний раз редактировалось sukhanchik; 17.03.2010 в 16:59.
За это сообщение автора поблагодарили: hated8 (1).
Старый 16.03.2010, 15:46   #2  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
3)в выражении отбора "where" сначала перечислять более уникальные поля, а потом менее уникальные - например надо писать "where inventTrans.TransRefId == 'journalId' && inventTrans.TransType == InventTransType.InventTransfer". А так писать нельзя: "where inventTrans.TransType == InventTransType.InventTransfer && inventTrans.TransRefId == 'journalId' ".
Вы это серьёзно?
Старый 16.03.2010, 16:26   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от fed Посмотреть сообщение
Я не уверен что ее лечить надо. Я просто начинал работать на Informix, дык вот там когда место в таблице блокировок кончалось (при массовых обновлениях), просто генерировалась ошибка и транзакция откатывалась. В MS SQL за счет эскалации эта проблема преврашается в несколько менее тяжелую - проблему конфликтов из за страничных блокировок. В оракле проблема исчерпания таблицы блокировок не возникает, поскольку информация о блокировках храниться собственно в страницах БД. Однако такой способ хранения информации о блокировках чреват некоторым падением производительности при работе с блокировками.
Так что:
а) не факт что надо лечить
б) не факт что побочные эффекты от лекарства не окажуться тяжелее болезни.
Но ведь если так рассуждать, то получится что для MS SQL нам нужен сервер с намного большим объемом памяти, чтобы гарантировать что её хватает и мы не скатываемся в эскалацию блокировок.

Реально конечно нужно смотреть схожие по объемы и числу активных сессий инсталляции и сравнивать.
Старый 16.03.2010, 16:33   #4  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Вы это серьёзно?
Абсолютно серьезно. Много таких мест переделал, когда возникали тормоза - менял местами поля в условии. Я сугубо практик, не теоретик. База медленно работает тогда, когда программисты не следят за тем, что у них в условии "where" написано. По более уникальному полю SQL-сервер сразу отсекает кучу ненужной информации.
В приведенном мною примере сервер быстро найдет складские проводки по коду журнала - их всего несколько десятков штук, а затем из этих нескольких десятков проводок выберет те, у которых тип - "Перенос". А если написать запрос наоборот, то сервер сначала будет искать все проводки с типом "Перенос" - их могут быть миллиноны.
Старый 16.03.2010, 16:51   #5  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
А если написать запрос наоборот, то сервер сначала будет искать все проводки с типом "Перенос" - их могут быть миллиноны.
Можете написать скрипт, который воспроизведет такое поведение?
Старый 16.03.2010, 17:10   #6  
SolNik is offline
SolNik
Участник
 
58 / 36 (2) +++
Регистрация: 22.10.2003
Цитата:
3)в выражении отбора "where" сначала перечислять более уникальные поля, а потом менее уникальные - например надо писать "where inventTrans.TransRefId == 'journalId' && inventTrans.TransType == InventTransType.InventTransfer". А так писать нельзя: "where inventTrans.TransType == InventTransType.InventTransfer && inventTrans.TransRefId == 'journalId' ".
Если бы у сиквела был такой тупой оптимизатор, его бы уже давно выкинули на помойку .
Неадекватное поведение могло быть связано с неактуальной статистикой, но никак не с порядком критериев в where.
Старый 16.03.2010, 17:25   #7  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Раз человек говорит, значит у него так и было и перестановка where помогла.
Только я подозреваю, что проблема не в where, а в последующем order by, который построен по этим же полям и включается соответствующей галкой.

и в целом, можно только за их компанию порадоваться
Цитата:
Работаю на базе данных MS SQL с 9 млн. проводок и 448 тыс. накладных. Никаких блокировок и тормозов нет. Все летает. Размер базы 150 ГБ.
Не парюсь со всякими хинтами типа forceplaceholders и forcenestedloops.
Старый 16.03.2010, 17:53   #8  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Цитата:
Сообщение от belugin Посмотреть сообщение
Можете написать скрипт, который воспроизведет такое поведение?
Вы наверное испытывате желание подловить меня на чем-то? То, что я предлагаю, работает лишь на сложных запросах. Найти стандартный пример я вам не могу, т.к. это зависит от многих условий, и на разных базах один и тот же запрос будет работать очень быстро или очень медленно.

Вот недавно оптимизированный в моей базе запрос, который зависал.

Запрос до оптимизации
PHP код:
static void Job296(Args _args)
{
    
someLine                            someLine;
    
someTable                           someTable;
    
WMSJournalTrans                     WMSJournalTrans;
    
purchLine                           purchLine;
    
boolean                             _OnlyPosted true;
    ;
        
Select Sum(NetWeight), Sum(InventQtyBoxes), Sum(InventQtyUnitsFrom someLine
            Where someLine
.ItemId == "ItemId"
            
exists join someTable
                
//group by TableId
                
Where
                      
(someTable.SomeType  == SomeEnum::FirstVariant ||
                       
someTable.SomeType  == SomeEnum::SecondVariant   ||
                       
someTable.SomeType  == SomeEnum::ThirdVariant) &&
                      !
someTable.IsCanceled &&
                      
someTable.RecId == someLine.ParentRecId //индексированное поле, уникальное для someTable
            
exists join WMSJournalTrans
                
//group by TableId
                
Where
                      
(WMSJournalTrans.fPosted  ||  !_OnlyPosted) &&
                       
WMSJournalTrans.someTableRecId  == someTable.RecId &&
                       
WMSJournalTrans.inventTransId == purchLine.InventTransId  //индексированное поле
;


Запрос после оптимизации
PHP код:
static void Job296(Args _args)
{
    
someLine                            someLine;
    
someTable                           someTable;
    
WMSJournalTrans                     WMSJournalTrans;
    
purchLine                           purchLine;
    
boolean                             _OnlyPosted true;
    ;
        
Select Sum(NetWeight), Sum(InventQtyBoxes), Sum(InventQtyUnitsFrom someLine
            Where someLine
.ItemId == "ItemId"
            
exists join someTable
                
//group by TableId
                
Where
                      someTable
.RecId == someLine.ParentRecId  && //индексированное поле, уникальное для someTable
                      
(someTable.SomeType  == SomeEnum::FirstVariant ||
                       
someTable.SomeType  == SomeEnum::SecondVariant   ||
                       
someTable.SomeType  == SomeEnum::ThirdVariant) &&
                      !
someTable.IsCanceled
            exists join WMSJournalTrans
                
//group by TableId
                
Where
                       WMSJournalTrans
.inventTransId == purchLine.InventTransId && //индексированное поле
                       
WMSJournalTrans.someTableRecId  == someTable.RecId &&
                      (
WMSJournalTrans.fPosted  ||  !_OnlyPosted);

За это сообщение автора поблагодарили: Logger (3).
Старый 16.03.2010, 17:57   #9  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
И мне непонятно желание подкольнуть меня. Неужто я что-то вредное предлагаю? Неужто внимательное написание запросов - это вредный совет? И неужто для вас так важно, вы так хотите не соблюдать порядок полей в условиях?

Последний раз редактировалось Ace of Database; 16.03.2010 в 18:01.
Старый 16.03.2010, 18:00   #10  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Намеренно оставил в комментариях кода //group by TableId .
Просто у нас тут тоже были спорщики, которые утверждали, что exists join тормозит. И пытались ускорить путем устранения exist join'а.
Пока не переставил местами поля в условиях отбора, ничего не помогало
Старый 16.03.2010, 18:01   #11  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
И мне непонятно желание подкольнуть меня. Неужто я что-то вредное предлагаю? Неужто внимательное написание запросов - это вредный совет? И неужто для вас так важно, вы так хотите не соблюдать порядок полей а условиях?
Просто вы описываете очень странное поведение системы, так что закономерно возникает подозрения что проблема не в сиквеле, а что вы не так что-то поняли.

Если все именно так и есть как вы говорите, то я сильно разочаруюсь в MS SQL
Старый 16.03.2010, 18:41   #12  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
5 лет назад я говорил, что "таких нет", кто будет выбирать в пользу MS SQL. Теперь я изменил свое мнение.
Работаю на базе данных MS SQL с 9 млн. проводок и 448 тыс. накладных. Никаких блокировок и тормозов нет. Все летает. Размер базы 150 ГБ.
Не парюсь со всякими хинтами типа forceplaceholders и forcenestedloops.
Везде использую exist join - очень удобно.
Вы бы хоть рассказали, какая используется версия Ms SQL (2005/2008), используется ли сжатие, если речь о 2008-м, какое у вас железо - очень было бы интересно это узнать. Потому что с точки зрения DBA, возможно, все и однозначно: лучше Oracle, потому что там больше настроек, потому что там есть RAC, потому что его можно поставить на (чей-нибудь любимый) *nix и все такое. Но с точки зрения компании в контексте TCO, по-моему, все не так однозначно: железо дешевеет и при этом становится мощнее и шустрее, а специалисты по ораклу, во-первых, "не растут на деревьях", а во-вторых, как отмечалось, "стоят типа дорого".
Еще, конечно, очень интересно было бы узнать про чей-нибудь опыт использования сжатия данных в Ms SQL 2008: по-моему, когда данные на диске сжимаются в разы, это должно как-то очень существенно повлиять на стратегии оптимизации запросов и различные весовые коэффициенты, в них используемые.
Старый 16.03.2010, 18:48   #13  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
Вот недавно оптимизированный в моей базе запрос, который зависал.

Запрос до оптимизации
....
Запрос после оптимизации
....

а можно привести ваши планы запросов в обоих случаях ?
Старый 16.03.2010, 18:49   #14  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
И мне непонятно желание подкольнуть меня. Неужто я что-то вредное предлагаю? Неужто внимательное написание запросов - это вредный совет? И неужто для вас так важно, вы так хотите не соблюдать порядок полей в условиях?
Ничего личного. Стратегия оптимизации логична и ясна. Просто необходимость проделывать её вручную ствится под сомнение. Нужно подобрать хороший пример и провести исследование данного вопроса.

P.S.: А как вы представляете себе соблюдение 'оптимальной' последовательности условий при конструировании запроса при помощи Query?
Старый 16.03.2010, 19:03   #15  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Вы бы хоть рассказали, какая используется версия Ms SQL (2005/2008), используется ли сжатие, если речь о 2008-м, какое у вас железо - очень было бы интересно это узнать. Потому что с точки зрения DBA, возможно, все и однозначно: лучше Oracle, потому что там больше настроек, потому что там есть RAC, потому что его можно поставить на (чей-нибудь любимый) *nix и все такое. Но с точки зрения компании в контексте TCO, по-моему, все не так однозначно: железо дешевеет и при этом становится мощнее и шустрее, а специалисты по ораклу, во-первых, "не растут на деревьях", а во-вторых, как отмечалось, "стоят типа дорого".
Еще, конечно, очень интересно было бы узнать про чей-нибудь опыт использования сжатия данных в Ms SQL 2008: по-моему, когда данные на диске сжимаются в разы, это должно как-то очень существенно повлиять на стратегии оптимизации запросов и различные весовые коэффициенты, в них используемые.
Сжатие у нас не используется. Про железо в данный момент ничего сказать не могу, так как оно меня не особенно интересует и я в нем не разбираюсь Сервер мы ставили год назад, и сейчас не знаю, где искать бумаги. Просто знаю, что пока мы не увеличили память, были проблемы с табличными блокировками.

Здесь я попытался акцентировать внимание на том, что от программирования очень много зависит - не меньше чем от железа. Запрос, который я здесь привел, выполнялся за 2 секунды до оптимизации. Но так как он вызывался столько раз, сколько строк в закупке, то система висела по несколько минут. После оптимизации закупки открываются моментально, независимо от количества строк в них.

И я не в коем случае не говорю, что MS SQL лучше, чем Oracle! Просто, MS SQL тоже пригоден для работы с большими объемами данных.


Забыл сказать: версия SQL - 2005

Последний раз редактировалось Ace of Database; 16.03.2010 в 19:16.
Старый 16.03.2010, 19:07   #16  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Ничего личного. Стратегия оптимизации логична и ясна. Просто необходимость проделывать её вручную ствится под сомнение. Нужно подобрать хороший пример и провести исследование данного вопроса.

P.S.: А как вы представляете себе соблюдение 'оптимальной' последовательности условий при конструировании запроса при помощи Query?
Query - ни в коем случае не использую в критических случаях. Использую только в отчетах и в тех местах, где прогон по всем записям осуществляется всего один раз. Для мелких функций, которые вызываются сотни раз, и для которых задержка в 1 секунду уже фатальна, Query не использую.
Старый 16.03.2010, 19:12   #17  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Ну хотя бы сколько памяти на сервере БД вы можете сказать ?
Старый 16.03.2010, 19:21   #18  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Завтра скажу
Старый 16.03.2010, 19:21   #19  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
Query - ни в коем случае не использую в критических случаях...
Согласен, с Query есть свои проблемы, но при желании их можно обойти. Помогите с Query
Старый 16.03.2010, 22:53   #20  
raz is offline
raz
NavAx
Аватар для raz
NavAx Club
Лучший по профессии 2014
Лучший по профессии 2009
 
1,494 / 1065 (38) ++++++++
Регистрация: 22.07.2003
Адрес: МО
Вероятнее всего проблема с изменением порядка полей и последующим ускорением/замедлением запросов лежит в плоскости оптимизатора аксапты, а не sql. В dax3 с какого-то kr оптимизатор аксапты начал сам подставлят индексы в запросы согласно условиям where.
Теги
index hint, sql server, оптимизация

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Параметры запросов БД CasperSKY DAX: Программирование 3 22.03.2008 19:32
Владельцы таблиц в БД аксапты AxaptaUser DAX: Администрирование 11 23.05.2007 18:33
Оптимизация запросов psv DAX: Администрирование 6 29.07.2004 23:17
Оптимизация запросов Mystery DAX: Программирование 3 25.02.2004 13:12
Просмотр SQL запросов к БД с помощью файла Log Anton Sk. DAX: База знаний и проекты 3 25.01.2002 16:31
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 19:08.