Переключение между выборками занимает очень много времени в Qlikview

Автор Софья, 08 мая 2015, 07:59:41

« назад - далее »

Софья

Добрый день.
Столкнулась с такой проблемой, что программа очень долго грузит/думает, когда я переключаю выборки. Буквально каждое новое действие, даже такое, как "Очистить", занимает примерно минуту, прежде чем программа подгрузит и выдаст мне данные.
Приложение рабочее, готово к использованию, но этот "маленький" изъян делает его непригодным для пользователей. У меня самой не хватает терпения сидеть и ждать, когда программа выдаст результат. Проблема критичная, из-за этого не могу отдать её пользователям в эксплуатацию.
Теперь более подробно:
Данные беру из базы Oracle, подключаю их при помощи OLE DB. Код за календарный год (2014) прогружается примерно 3 дня - месяц в районе 5 часов. Сформировала QVD-файл за данный период, чтобы программа из него брала данные. QVD-файл занимает 4,6 ГБ, а само приложение - 1,4 ГБ. Итог про "быстродействие" данного приложения Вы уже знаете.
Что насчёт аппаратных средств, не могу понять, в них дело или нет. ОЗУ доступная - 64 ГБ, причём, когда переключаю выборку, диспетчер задач показывает загрузку ЦП 100%, физическая память забивается  примерно до 40 ГБ, останавливается, хотя ещё 20 ГБ есть в запасе, и QlikView пишет:"Не хватает памяти" вместо данных в сводной таблице.
Подскажите, что это означает? Где не хватает памяти? Памяти, ведь, ещё предостаточно. Как оптимизировать работу программы, чтобы она быстро реагировала на переключение выборок?
Что насчёт вкладок со сводными таблицами, то уже убрала 2 вкладки - оставила только "Сводку по магазинам". В ней 7 вычисляемых выражений, ничего криминального в них нет, как по мне, чтобы они влияли на скорость работы приложения.
Вот они:
Sum(факт_цена*кол-во_товара) as СУММА ЗА ДЕНЬ;
Sum(роз_цена*кол-во_товара) as СУММА РОЗНИЧНАЯ;
Sum(If(Безнал = 1, факт_цена*кол-во_товара, 0)) as БЕЗНАЛ;
((Sum(роз_цена*кол-во_товара)- Sum(факт_цена*кол-во_товара))*100)/ Sum(факт_цена*кол-во_товара) as % СКИДКИ;
Sum(роз_цена*кол-во_товара)- Sum(факт_цена*кол-во_товара) as СКИДКА В РУБ.;
Sum(факт_цена*кол-во_товара)/Count(Distinct чек & Partn_doc) as СРЕДНИЙ ЧЕК;
Count(Distinct чек & Partn_doc) as КОЛ-ВО ЧЕКОВ.

Сам код:

SET vL1Date = "'01.01.2014 00:00:00','DD.MM.YYYY HH24:MI:SS'";     
SET vL2Date = "'31.12.2014 23:59:59','DD.MM.YYYY HH24:MI:SS'";
SET vDo1Date = "'30.12.2013 00:00:00','DD.MM.YYYY HH24:MI:SS'";     
SET vDo2Date = "'02.01.2015 23:59:59','DD.MM.YYYY HH24:MI:SS'";
Документы:
LOAD ID AS ID_DOCUMENT,     
    TYPE AS ТИП,   
    DEPARTMENT AS ID_DEPARTMENT,
    DOC_DATE,
    SECOND(DOC_DATE) AS SECOND,           
    MINUTE(DOC_DATE) AS MINUTE,
    HOUR(DOC_DATE) AS HOUR,                         
    DAY(DOC_DATE) AS DAY,
    WEEKDAY(DOC_DATE) AS DAYNAMES,
    MONTH(DOC_DATE) AS MONTH,
    YEAR(DOC_DATE) AS YEAR,
    PRODUCT AS ID_PRODUCT,
    F15007748 AS ЦЕНА,
    F15007746 AS РОЗ_ЦЕНА,
    F14286852 AS КОЛВО_ТОВАРА,
    LINE_NO AS ЧЕК,
    BEZNAL AS БЕЗНАЛ,
    VOZVRAT AS ВОЗВРАТ,
    POZ AS КОЛВО_ПОЗИЦИЙ;     
SQL SELECT --+ INDEX(DB1_DOCUMENT DB1_DOCUMENT_BY_TYPE_DATE)
    D1.ID,
    D1.TYPE,
    D1.DEPARTMENT,
    TO_CHAR(TRUNC(L.F14286866), 'dd.mm.yyyy') AS DOC_DATE,
    L.PRODUCT,
    L.F15007748,
    L.F15007746,
    L.F14286852,
    L.LINE_NO,
    (SELECT CASE WHEN L2.F6684673 = HEXTORAW('0095000101BC0001') THEN 0 ELSE 1 END
    FROM ETK00."DB1_LINE" L2 WHERE L2.DOCUMENT = D1.ID AND L2.TYPE = 40304642 AND L2.LINE_NO = L.LINE_NO AND ROWNUM <= 1) AS BEZNAL,
    (CASE WHEN L.F14286852 > 0 THEN 0 ELSE 1 END) AS VOZVRAT,
    (SELECT COUNT(*) FROM ETK00."DB1_LINE" where DOCUMENT = D1.id and TYPE = 40304641 and LINE_NO = L.LINE_NO) AS POZ
FROM ETK00."DB1_DOCUMENT" D1, ETK00."DB1_LINE" L
WHERE D1.CLASS = 40304641
AND D1.TYPE = 40304641
AND D1.STATE = 1
AND L.TYPE = 40304641
AND D1.ID = L.DOCUMENT
AND D1.DOC_DATE >= TO_DATE($(vDo1Date))
AND D1.DOC_DATE <= TO_DATE($(vDo2Date))
AND L.F14286866 >= TO_DATE($(vL1Date))
AND L.F14286866 <= TO_DATE($(vL2Date));

Буду весьма признательна за любую помощь.

admin

Добрый день.
При переключении выборок происходит перерасчет всех выражений по всем объектам.
Модель данных без переменных-выражений и объектов также ведет себя при изменении параметров выборки?

Софья

Если убрать сводную таблицу и добавить несколько списков, то работает намного быстрее.
Но вся проблема в том, что нужен именно этот набор вычисляемых данных, не меньше. Это пожелание пользователей. Они точно не собираются из-за каждого параметра открывать новое приложение, им необходимы эти данные в таблице единой.
Скажите, может быть проблема в железе? Или всё же нужно оптимизировать код? Хотя не представляю, что ещё можно убрать при выданном мне ТЗ.

admin

Самое первое - оптимизация.
Рассмотрите возможность вычисления показателей/мер в скрипте. Может произойти увеличение размера данных в модели но вычислений при смене выборок станет меньше.


kvv

Добрый день.
Как вариант, посмотрите на быстродействие дисков. Может быть, что они "притормаживают".

Софья

Admin, спасибо за материалы, попробую оптимизировать, насколько будет возможно.

А как проверить быстродействие дисков, не подскажите? В железе я не сильна, признаться.

bibis

Добрый день. Ну бы не сказал ,что count distinct да еще и конкантенации 2х полей это "ничего криминального" :D
"if" кстати тоже лучше заменить set анализом, тут я правда сам не понял аргументов, но умные люди говорят- лучше заменить.
Ну и да, присоединяюсь, если загрузка идёт нечасто, всегда лучше все расчеты в скрипт засунуть.

kvv

Цитата: Софья от 08 мая  2015, 10:21:16  
А как проверить быстродействие дисков, не подскажите? В железе я не сильна, признаться.

1. Мониторинг ресурсов - в командной строке Windows наберите "perfmon /res".
https://www.youtube.com/watch?v=oIhYT7Urbk4 - Монитор ресурсов Windows.

2. Кстати, а какой процессор на сервере? Вы писали что он грузиться 100%.

3. По-поводу быстродействия QlikView, мне понравилось вот это - https://community.qlik.com/servlet/JiveServlet/downloadBody/3732-102-1-4322/Optimizing_Qlikview.docx. Простые рекомендации, но часто они помогают.

Софья

Bibis, проблема сейчас как раз в том, что я не пока знаю, как это в скрипте прописать. Согласно этим формулам, получается, что я пытаюсь вернуть сумму по одному значению - естественно, это некорректно, поэтому SQL Developer много ошибок выдаёт, либо 0-ли по всем строкам. Как раз нужен массив данных, чтобы приложение работало адекватно, именно поэтому я вынесла все эти формулы во внешнее отображение.

Kvv, процессор - Intel(R) Core(TM) i7-3930k CPU @ 3.20GHz.
А этот документ по оптимизации я уже этот скачала.

Спасибо за советы, теперь знаю, в каком направлении работать.

admin

Рассмотрите вариант расчета значений средствами Qlikview не в SQl запросе а на этапе обработки QVD-файла, сформированного из источника.

Софья

Добрый день.
Читаю документы, которые Вы мне отправили, но так и не могу разобраться в синтаксисе QlikView, а именно - где и как прописывать выражения в самом скрипте.
Есть поля, прогруженные из QVD-файла:
Документы:     
LOAD ID_DOCUMENT,
     ТИП,
     ID_DEPARTMENT,
     PARTN_DOC,
     DOC_DATE,
     SECOND,
     MINUTE,
     HOUR,
     DAY,
     DAYNAMES,
     MONTH,
     YEAR,
     ID_PRODUCT,
     ЦЕНА,
     РОЗ_ЦЕНА,
     КОЛВО_ТОВАРА,
     ЧЕК,
     БЕЗНАЛ,
     ВОЗВРАТ,
     КОЛВО_ПОЗИЦИЙ
FROM
[C:\Users\1\Desktop\January2014.qvd]
(qvd);

Мне нужно добавить такое вычисляемое поле, как сумма. Это количество*цену. Прописываю:
Документы:     
LOAD ID_DOCUMENT,
     ТИП,
     ID_DEPARTMENT,
     PARTN_DOC,
     DOC_DATE,
     SECOND,
     MINUTE,
     HOUR,
     DAY,
     DAYNAMES,
     MONTH,
     YEAR,
     ID_PRODUCT,
     ЦЕНА,
     РОЗ_ЦЕНА,
     КОЛВО_ТОВАРА,
     ЧЕК,
     БЕЗНАЛ,
     ВОЗВРАТ,
     КОЛВО_ПОЗИЦИЙ,
     sum(КОЛВО_ТОВАРА*ЦЕНА) as СУММА
FROM
[C:\Users\1\Desktop\January2014.qvd]
(qvd);

Отладчик выдаёт ошибку - "Invalid expression".
Вот и хотела разобраться, где непосредственно прописываются выражения и все расчёты в QlikView? После LOAD до FROM? В чём у меня ошибка, в синтаксисе? Чувствую, что опять лезу с синтаксисом SQL.
Заранее благодарна за ответ.

admin

День добрый.
SUM() в запросах используется только с group by, иначе интерпретатор не понимает что вы хотите сделать.
Просто  перемножайте два поля, и вы получите сумму по каждой строке, которую уже в объектах визуализации будете суммировать.

Софья

Так я уже делала, перемножала необходимые поля, а во внешнее отображение выносила эти рассчитанные поля, только Sum добавляла в агрегировании.
"Быстродействие" такое же - несносное.

admin

sum() не сильно тормозит систему.
В вашем наборе выражений
Sum(факт_цена*кол-во_товара) as СУММА ЗА ДЕНЬ;
Sum(роз_цена*кол-во_товара) as СУММА РОЗНИЧНАЯ;
Sum(If(Безнал = 1, факт_цена*кол-во_товара, 0)) as БЕЗНАЛ;
((Sum(роз_цена*кол-во_товара)- Sum(факт_цена*кол-во_товара))*100)/ Sum(факт_цена*кол-во_товара) as % СКИДКИ;
Sum(роз_цена*кол-во_товара)- Sum(факт_цена*кол-во_товара) as СКИДКА В РУБ.;
Sum(факт_цена*кол-во_товара)/Count(Distinct чек & Partn_doc) as СРЕДНИЙ ЧЕК;
Count(Distinct чек & Partn_doc) as КОЛ-ВО ЧЕКОВ.

есть куда более затратные в плане ресурсов комбинации функций.
Вы хотите сказать, что сделали расчет первых пяти выражений в скрипте, заменили выражения в объектах и ничего не изменилось?
Как поступили с расчетом СРЕДНИЙ ЧЕК и КОЛ-ВО ЧЕКОВ ?

Яндекс.Метрика