25.12.2011, 18:46 | #21 |
Участник
|
Цитата:
А ключевая проблема в том что выборка по двум таблицам принципиально плохооптимизируемая операция. Например некорректное решение структуры данных при объемах данных порядка биллиона операций хоронит проект... Но чаще всего мы работаем с маленькими таблицами. При этом мы работаем кое как - и все работает быстро. И тогда лагание на десятках миллионов записей всех ставит в тупик... Последний раз редактировалось Мартынов Дмитрий; 25.12.2011 в 18:51. Причина: про кое как забыл написать |
|
25.12.2011, 18:52 | #22 |
Moderator
|
Цитата:
Сообщение от Мартынов Дмитрий
Интересно, что когда я не вдаюсь в технические детали - то меня начинаю обвинять в невежестве... Разница между B-деревом и сортированной таблицей с точки зрения нашей задачи небольшая. Более того если мы создаем правильные структуры данных и делаем правильные запросы, то разница между ними вообще не в пользу B-дерева.
Цитата:
Сообщение от Мартынов Дмитрий
Хотите - можно написать на Х++, вместо таблиц здесь можно использовать контейнер без операции поиска, только с запоминанием индекса элемента. Суть задачи сводится к выборке по двум таблицам и четырем индексам: фильруем по полю 1 в первой таблице, связываем по полю 2 таблицы, фильтруем по полю 3 вторую таблицу. В первой таблице есть 2 индекса по полю 1 и полю 2 соответственно, аналогично во второй есть индексы по полям 2 и 3.
Цитата:
Сообщение от Мартынов Дмитрий
А ваше предположение что авторы которые пишут SQL сервер обладают тайным знанием - в корне неверно, скорее те кто использую SQL по большей части бездари и по этому разница бросается в глаза... Но вы fed уж не обижайтесь - я не про Вас, ваши обиды мне дорого обходятся...
|
|
25.12.2011, 19:03 | #23 |
Участник
|
Цитата:
Интересно было бы увидеть более развернутый ответ. А то вы вроде начали, а по существу ничего не написали. Отделались общими словами. По поводу памяти - поясняю. На нашем проекте база крутится с 2005-го года. Стартовали на 3-ке. в 2006 году заметили явные подтормаживания на запросах когда был джоин по InventSum и InventDim с фильтром по складу и номенклатуре (ItemId like 'XXX%' . (Нам важно было достичь быстрого времени отклика - порядка доли секунды). Проблему решили денормализацией InventSum. Добавили туда поле склад, проиндексировали, а InventDim из джоина выкинули. Система словно задышала. Все сразу стало быстрее. Админ был очень доволен - сказал что память используется намного меньше. Но когда я сейчас попробовал построить пример и замерять время, то с удивлением обнаружил что разницы практически нет. Результат поразительный. Пока вижу причину в том что в 2006 году был другой сервер БД, в котором стояло совсем немного памяти. А сейчас памяти навалом. Но чтобы точно можно было сказать - придется провести дополнительные тесты. |
|
25.12.2011, 19:40 | #24 |
Участник
|
Цитата:
Сообщение от Logger
По поводу памяти - поясняю. На нашем проекте база крутится с 2005-го года. Стартовали на 3-ке. в 2006 году заметили явные подтормаживания на запросах когда был джоин по InventSum и InventDim с фильтром по складу и номенклатуре (ItemId like 'XXX%' . (Нам важно было достичь быстрого времени отклика - порядка доли секунды). Проблему решили денормализацией InventSum. Добавили туда поле склад, проиндексировали, а InventDim из джоина выкинули. Система словно задышала. Все сразу стало быстрее. Админ был очень доволен - сказал что память используется намного меньше.
|
|
25.12.2011, 19:47 | #25 |
Участник
|
Цитата:
Сообщение от Pustik
Не поленился. На тестовой базе сделал аля InventTrans2. Сделал поле Склад. Джобом перекопировал данные из стандартного InventTrans(c учетом склада) в новый InventTrans2. Отрихтовал оборотку (убрал из джоина InventDim). Отчет выдал информацию в 10 раз быстрее, причем за год, по всем складам. По конкретному складу, вообще нечего говорить, если настроить в InventTrans2 индекс.
Если примените на рабочей, опубликуйте, пожалуйста, результат для системы под нагрузкой. Причем именно на InventTrans и не на копии. Интересно сравнить результаты. Подозреваю что разница будет еще больше. |
|
25.12.2011, 19:52 | #26 |
Участник
|
Цитата:
Цитата:
Сообщение от fed
Не хочешь чтобы над тобою стебались, почитай для начала Вирта "Алгоритмы и структуры данных (про B-Деревья и Хэш-таблицы) и почитай в BOL про виды джойнов в SQL Server. Еще можно почитать блог Craig Freeman Так что знания не тайные, просто, вероятно, твой ''научный подход" - это такое политически корректный термин для "невежество".
|
|
26.12.2011, 08:23 | #27 |
Участник
|
|
|
26.12.2011, 08:53 | #28 |
Участник
|
|
|
26.12.2011, 09:09 | #29 |
Участник
|
Цитата:
И как в этой таблице искать?
__________________
Axapta v.3.0 sp5 kr2 |
|
26.12.2011, 09:31 | #30 |
Участник
|
|
|
26.12.2011, 14:55 | #31 |
Участник
|
Цитата:
Сообщение от fed
Очень странно, что перенос склада в inventTrans дал такой прирост производительности. Могу поверить в типичный показатель накладных расходов на джойн двух таблиц в 40-50%. Могу поверить на нетипичные случаи с 200% накладных расходов. Не могу поверить в накладные расходы в 900%
Мне кажется, у вас там просто какая-то беда с планом запроса в стандартной оборотке. Может статистика кривая, может сам сиквел глючит почему-то, может индексы не перестраивались несколько лет. В общем - попробуйте план запроса выщемить и выложить. Вот пример из реальной базы inventTrans - 22 млн записей inventDim - 4 млн записей Включены аналитики - склад (~ 10 складов, по каждому из складов примерно пропорциональной движение товара по количеству операций) - партия - ячейка запрос, код которого ниже (вызывается одним из наших отчетов Аксапта) X++: Use Axapta; SELECT SUM(A.QTY), SUM(A.COSTAMOUNTPOSTED), SUM(A.COSTAMOUNTADJUSTMENT), A.ITEMID, A.DIRECTION FROM INVENTTRANS A WHERE A.DATAAREAID=N'cmp' AND A.DATEFINANCIAL>={ts '2010-12-01 00:00:00.000'} AND A.DATEFINANCIAL<={ts '2010-12-31 00:00:00.000'} AND EXISTS (SELECT 'x' FROM INVENTDIM B WHERE ((B.DATAAREAID=N'cmp') AND ((B.INVENTLOCATIONID=N'Магазин3') AND (A.INVENTDIMID=B.INVENTDIMID)))) GROUP BY A.ITEMID,A.DIRECTION ORDER BY A.ITEMID,A.DIRECTION Вряд ли добавление поля "код склада" в InventTrans как то повлияет на производительность... Интересно а как с этим у других ? |
|
26.12.2011, 14:59 | #32 |
----------------
|
someOne. тут много чего можно оптимизировать
а уж с полем склад вообще будет лётать |
|
26.12.2011, 15:04 | #33 |
Участник
|
Цитата:
По вашему после добавления поля "склад" в таблицу InventTrans он (этот запрос) будет исполняться за 2 секунды ? Я сильно в этом сомневаюсь... |
|
26.12.2011, 15:25 | #34 |
Участник
|
Цитата:
inventDim - 11 млн записей (склад,размер,партия) 170 складов, 40 тыс. номенклатур (это к тому, что у вас же там группировка и сортировка по ItemId). Возвращает результат (10 тыс строк) за 5 мин 22 сек - очень даже есть что оптимизировать. |
|
|
За это сообщение автора поблагодарили: someOne (3). |
26.12.2011, 16:23 | #35 |
Участник
|
Я, конечно, извиняюсь, но если речь идет об отчетах, то почему не делать прямые запросы к серверу через Connection + Statment + ResultSet? Это ускоряет выполнение отчета даже не в разы, а на порядки. Правда, за счет потери универсальности настроек отчета.
Именно по этой причине (потеря универсальности настроек отчета) такой подход невозможен в "стандарте". Но ведь речь идет о кастомизации под требования конкретного клиента. Т.е. не "общее для всех", а под одного конкретного клиента. Как частное решение - вполне уместно. Как мне кажется, оптимизация структуры данных не даст такого уж принципиального выигрыша производительности, если отчет будет по прежнему выполяться "штатными" средствами. Тут много разных причин.
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
26.12.2011, 16:42 | #36 |
Участник
|
Так здесь обсуждается именно структура данных.
А то о чем вы говорите - тоже поможет, но это совсем из другой оперы. Кстати, неужели прямо в разы разница ? |
|
26.12.2011, 18:10 | #37 |
Ищущий знания...
|
Цитата:
Скажу откровенно, SQL на глубоком уровне я не знаю, поэтому опирировать техничисками понятия SQL не смогу, а буду оперировать фактами, которые были. Единственный нюанс, который я могу осознанно освятить, это то что таблица InventTrans у нас лежала на отдельно физическом диске (возможно это и сказалось, не знаю) После добавления поля InventLocationId в таблицу InventTrans время работы отчетов, где была связка двух таблиц InventTrans + InventDim и на InventDim условие по складу, сократилось в 10-ки раз (с ~25-30 мин до ~1-2минут)! Объяснения этому я нашел такие (не совсем технические): 1. Системе проще искать в одной большой таблице, чем в двух больших таблицах (все таки, как мне кажется, выбрать данные из 22млн строк быстрее, чем из 28 млн строк да ещё и в разных местах хранящихся). Что я имею ввиду. Например, нам нужно выбрать данные из InventTrans за один день, по одному складу. При выполлнении запроса из InventTrans выбирались данные за этот день, по всем складам, которых было порядка двухста (200) (да использовался индекс по дате, но все равно много записей)... потом выбирались аналитики (InventDim) с указанным складом (тут записей не очень много), и затем уже на основе полученных аналитик фильтровались проводки (InventTrans). И на все эти операции SQL тратило время. 2. В те времена использовался SQL2005, и как мне объясняли при джойнах SQL собирал временную табличку по двум табличкам, на это тоже тратилось время. После добавления поля InventLocationId в InventTrans, система стала искать записи по индексу Дата+Склад (ну там ещё компания, но мы сейчас не про неё), в одной табличке, и поэтому SQL стало тратить время только на выобрку данных из индекса... З.Ы. возможно мои выводы ошибочны, тогда прошу меня поправить... и тогда я не понимаю, почему был такой прирост производительности
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем Последний раз редактировалось sukhanchik; 26.12.2011 в 18:20. Причина: Орфография |
|
26.12.2011, 18:46 | #38 |
Участник
|
Про "разницу в разы" вопрос был к Владимиру Максимову. Не верится что прямой запрос к БД настолько быстрее работает. |
|
26.12.2011, 20:26 | #39 |
Участник
|
Цитата:
Ну, например, стандартная задача. Получить сумму отгрузки за период в отгрузочных ценах. Проблема в том, что количество надо взять из складской проводки, а цену - из строки заказа. Значит, средствами Axapta надо вытянуть и то и другое, а потом уже сложить на клиенте. Средствами SQL я это сделаю в самом запросе. Если применительно к складской аналитике, то, например, получить остатки всех товаров на дату в разрезе складской аналитики средствами SQL на несколько порядков быстрее, чем средствами Axapta. Вот уж с этим я долго мучился Средствами Axapta отчет работает часами (без преувеличения), а средствами SQL - максимум несколько минут.
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
27.12.2011, 10:12 | #40 |
Участник
|
Цитата:
Сообщение от Владимир Максимов
Если применительно к складской аналитике, то, например, получить остатки всех товаров на дату в разрезе складской аналитики средствами SQL на несколько порядков быстрее, чем средствами Axapta. Вот уж с этим я долго мучился Средствами Axapta отчет работает часами (без преувеличения), а средствами SQL - максимум несколько минут.
Ограниченность X++ на котором не выразишь все идеи, которые можно сделать одним запросом на SQL ? Или накладные расходы внутри аоса при разборе полученной выборки и передаче её в X++ ? |
|