Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 [2]  Все   Вниз
  Печать  
Автор Тема: возможно ли оптимизировать этот запрос?  (Прочитано 49522 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #30 : 26-10-2010 08:46 » 

продолжение Улыбаюсь

известно, что для каждого типа ('N','U','A',...) не нужны все записи таблицы лога. То есть, к примеру, для первого типа нужны 10 полей, для второго 5 полей, для третьего 7 полей. Как-то с таким знанием можно ещё оптимизацию провести? Тут дело в чём - клиент тащит по локальной сети из БД записи для себя, а сделано немного коряво, так что записей тащится вагон
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #31 : 26-10-2010 09:29 » 

а есть что-нибудь типа limit, top, rownums?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #32 : 26-10-2010 09:47 » 

а это что, зачем
Записан

baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #33 : 26-10-2010 14:04 » 

Мне кажется это можно через HAVING сделать.. Лех, приведи запрос как он сейчас есть?
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #34 : 26-10-2010 14:20 » 

Леш, попробуй в SELECT выражение типа:

Код: (SQL)
  CASE nua_XYZ
    WHEN 'N' THEN field_XYZ
    WHEN 'U' THEN field_XYZ
    ELSE NULL
  END AS field_XYZ

Длинновато, но для 'N' и 'U' вернется полноценное поле, а для остальных - только NULL.

Т.е. выводи все 10 полей, но ненужные в ненужных условиях заменяй на NULL.
« Последнее редактирование: 26-10-2010 17:23 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #35 : 26-10-2010 15:50 » 

baldr, щас скомпилю, изображу Улыбаюсь Дома машинка не шустрая.

RXL, длинно - это ладно, больше интересует, скажется ли это на производительности выборки ?
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #36 : 26-10-2010 15:58 » 

baldr, вот
Код:
CREATE PROCEDURE PR_SHOWLOG_GET_MESSAGES(
    ID_TOLOADRFOMEXCLUDING BIGINT,
    ID_MAX BIGINT,
    MESSFILTER_BARR VARCHAR(513),
    MESSFILTER_LARS VARCHAR(37),
    MESSFILTER_REST SMALLINT)
RETURNS (
    MESSAGE_ID BIGINT,
    QUIT_DATE TIMESTAMP,
    DMESSAGE TIMESTAMP,
    NOMER SMALLINT,
    RAZDEL SMALLINT,
    MESS_TYPE SMALLINT,
    QUIT_REASON SMALLINT,
    COLOR SMALLINT,
    NUA_TYPE SMALLINT,
    NEW_COD_X77_MESS SMALLINT,
    DATAWORD INTEGER,
    CANAL_NUMBER SMALLINT,
    CANALNUMBER_PER SMALLINT,
    POWER_LEVEL VARCHAR(2),
    USERID SMALLINT,
    OPERID SMALLINT,
    F_18_GUARDEDNOW SMALLINT,
    TAGPOINTID32 INTEGER,
    NON_TECH_SMS_COUNT SMALLINT,
    ADR_GUID_M4S VARCHAR(32),
    CHOP_NUM_M4S SMALLINT,
    DELTA_TIME_CHOP_M4S INTEGER)
AS
 begin
    -- :messfilter_Rest имеет значение NULL, 0 или 1 - чисто для U и A сообщений
    -- :messfilter_barr имеет вид '~dec1~dec2~dec3~'
    -- :messfilter_barr VARCHAR(e_m_cs_FilterForMail_Param_Barr_LEN_tx)
    -- :messfilter_Lars имеет вид '~dec1~dec2~dec3~'
    -- :messfilter_Lars VARCHAR(e_m_cs_FilterForMail_Param_Lars_LEN_tx)
   for
   SELECT
  MESSAGE_ID
, QUIT_DATE
, DMESSAGE
, NOMER                 
, RAZDEL               
, MESS_TYPE             
, QUIT_REASON           
, COLOR                 
, NUA_TYPE             
, NEW_COD_X77_MESS     
, DATAWORD             
, CANAL_NUMBER         
, CANALNUMBER_PER       
, POWER_LEVEL           
, USERID               
, OPERID               
, F_18_GUARDEDNOW       
, TAGPOINTID32         
, NON_TECH_SMS_COUNT   
, ADR_GUID_M4S         
, CHOP_NUM_M4S         
, DELTA_TIME_CHOP_M4S   
   FROM MESS_LOG WHERE (MESSAGE_ID between :ID_toLoadrfomExcluding+1 and :ID_Max)
   and
    (
        (
                  -- 'N'
             NUA_TYPE=78
        )
        and
        (
             -- cNT_4p2_CMD_92_txt
            (MESS_TYPE!=92) and (:messfilter_barr is null or :messfilter_barr containing '~'||MESS_TYPE||'~')
         or
            (MESS_TYPE =92) and (:messfilter_Lars is null or :messfilter_Lars containing '~'||TYPEFOR_CLIENTFILTER||'~')
        )
     
      or
             --  'U'    'A'
        (NUA_TYPE=85 or NUA_TYPE=65) AND (:messfilter_Rest is null or :messfilter_Rest=1)
     
      or
             --    'N'             'U'              'A'
        (NUA_TYPE!=78 and NUA_TYPE!=85 and NUA_TYPE!=65)
    )
   ORDER BY MESSAGE_ID DESC
   into
 :MESSAGE_ID
,:QUIT_DATE
,:DMESSAGE
,:NOMER                 
,:RAZDEL               
,:MESS_TYPE             
,:QUIT_REASON           
,:COLOR                 
,:NUA_TYPE             
,:NEW_COD_X77_MESS     
,:DATAWORD             
,:CANAL_NUMBER         
,:CANALNUMBER_PER       
,:POWER_LEVEL           
,:USERID               
,:OPERID               
,:F_18_GUARDEDNOW       
,:TAGPOINTID32         
,:NON_TECH_SMS_COUNT   
,:ADR_GUID_M4S         
,:CHOP_NUM_M4S         
,:DELTA_TIME_CHOP_M4S   
   do suspend;
 
 end
« Последнее редактирование: 26-10-2010 16:00 от Алексей1153++ » Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #37 : 26-10-2010 17:25 » 

Леш, в чем тут оптимизация?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #38 : 26-10-2010 18:27 » 

тут её ещё нету, это по просьбе Лёхи я привёл текст процедуры
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #39 : 26-10-2010 20:44 » 

Offtopic:

Поле NEW_COD_X77_MESS часом не в честь Игоря названо? Ага
Поставлю в угол.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #40 : 27-10-2010 03:20 » 

RXL, хм, я даже не обращал внимания )))) А ведь, вполне может быть.  Это флаг, показывающий, что используется новая кодировка, он как-то раньше назывался вообще незапоминаемо, я его года 3 назад переназвал, чтоб точно помнить  - вполне может быть, что по нику Игоря ))) Наверное, был очередной аврал
« Последнее редактирование: 27-10-2010 03:23 от Алексей1153++ » Записан

baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #41 : 27-10-2010 08:46 » 

Алексей1153++, а в условии тебе советовали CASE использовать - есть такой оператор в ОгнеПтице?
А чтобы уменьшить кол-во записей.. Сорри что может немного не работать - писал для MySQL, но идея должна быть понятна:
Код:
CREATE PROCEDURE PR_SHOWLOG_GET_MESSAGES(
    ID_TOLOADRFOMEXCLUDING BIGINT,
    ID_MAX BIGINT,
    MESSFILTER_BARR VARCHAR(513),
    MESSFILTER_LARS VARCHAR(37),
    MESSFILTER_REST SMALLINT)
RETURNS (
    MESSAGE_ID BIGINT,
    QUIT_DATE TIMESTAMP,
    DMESSAGE TIMESTAMP,
    NOMER SMALLINT,
    RAZDEL SMALLINT,
    MESS_TYPE SMALLINT,
    QUIT_REASON SMALLINT,
    COLOR SMALLINT,
    NUA_TYPE SMALLINT,
    NEW_COD_X77_MESS SMALLINT,
    DATAWORD INTEGER,
    CANAL_NUMBER SMALLINT,
    CANALNUMBER_PER SMALLINT,
    POWER_LEVEL VARCHAR(2),
    USERID SMALLINT,
    OPERID SMALLINT,
    F_18_GUARDEDNOW SMALLINT,
    TAGPOINTID32 INTEGER,
    NON_TECH_SMS_COUNT SMALLINT,
    ADR_GUID_M4S VARCHAR(32),
    CHOP_NUM_M4S SMALLINT,
    DELTA_TIME_CHOP_M4S INTEGER)
AS
 begin
    -- :messfilter_Rest имеет значение NULL, 0 или 1 - чисто для U и A сообщений
    -- :messfilter_barr имеет вид '~dec1~dec2~dec3~'
    -- :messfilter_barr VARCHAR(e_m_cs_FilterForMail_Param_Barr_LEN_tx)
    -- :messfilter_Lars имеет вид '~dec1~dec2~dec3~'
    -- :messfilter_Lars VARCHAR(e_m_cs_FilterForMail_Param_Lars_LEN_tx)
    SET @a=0;
    SET @b=-1;
   for
   SELECT MESSAGE_ID
, QUIT_DATE
, DMESSAGE
, NOMER                 
, RAZDEL               
, MESS_TYPE             
, QUIT_REASON           
, COLOR                 
, NUA_TYPE             
, NEW_COD_X77_MESS     
, DATAWORD             
, CANAL_NUMBER         
, CANALNUMBER_PER       
, POWER_LEVEL           
, USERID               
, OPERID               
, F_18_GUARDEDNOW       
, TAGPOINTID32         
, NON_TECH_SMS_COUNT   
, ADR_GUID_M4S         
, CHOP_NUM_M4S         
, DELTA_TIME_CHOP_M4S FROM (
   SELECT
  MESSAGE_ID
, QUIT_DATE
, DMESSAGE
, NOMER                 
, RAZDEL               
, MESS_TYPE             
, QUIT_REASON           
, COLOR                 
, NUA_TYPE             
, NEW_COD_X77_MESS     
, DATAWORD             
, CANAL_NUMBER         
, CANALNUMBER_PER       
, POWER_LEVEL           
, USERID               
, OPERID               
, F_18_GUARDEDNOW       
, TAGPOINTID32         
, NON_TECH_SMS_COUNT   
, ADR_GUID_M4S         
, CHOP_NUM_M4S         
, DELTA_TIME_CHOP_M4S
, @a:=if(@b=NUA_TYPE, @a, 0)+1 a, @b:=NUA_TYPE b
, case NUA_TYPE
    when 1 then 10
    when 2 then 5
    when 3 then 7
    end typelimit
   FROM MESS_LOG WHERE (MESSAGE_ID between :ID_toLoadrfomExcluding+1 and :ID_Max)
   and
    (
        (
                  -- 'N'
             NUA_TYPE=78
        )
        and
        (
             -- cNT_4p2_CMD_92_txt
            (MESS_TYPE!=92) and (:messfilter_barr is null or :messfilter_barr containing '~'||MESS_TYPE||'~')
         or
            (MESS_TYPE =92) and (:messfilter_Lars is null or :messfilter_Lars containing '~'||TYPEFOR_CLIENTFILTER||'~')
        )
     
      or
             --  'U'    'A'
        (NUA_TYPE=85 or NUA_TYPE=65) AND (:messfilter_Rest is null or :messfilter_Rest=1)
     
      or
             --    'N'             'U'              'A'
        (NUA_TYPE!=78 and NUA_TYPE!=85 and NUA_TYPE!=65)
    )
   ORDER BY NUA_TYPE) Q1 where a<typelimit ORDER BY MESSAGE_ID DESC
   into
 :MESSAGE_ID
,:QUIT_DATE
,:DMESSAGE
,:NOMER                 
,:RAZDEL               
,:MESS_TYPE             
,:QUIT_REASON           
,:COLOR                 
,:NUA_TYPE             
,:NEW_COD_X77_MESS     
,:DATAWORD             
,:CANAL_NUMBER         
,:CANALNUMBER_PER       
,:POWER_LEVEL           
,:USERID               
,:OPERID               
,:F_18_GUARDEDNOW       
,:TAGPOINTID32         
,:NON_TECH_SMS_COUNT   
,:ADR_GUID_M4S         
,:CHOP_NUM_M4S         
,:DELTA_TIME_CHOP_M4S   
   do suspend;
 
 end

Для начала можно тут убрать typelimit (во внешнем select заменить его на 10 в where, например) и case - и посмотреть будет ли возвращать по 10 записей
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #42 : 27-10-2010 09:06 » 

подзапрос тут точно не работает

case есть, работает. Но с ним по быстрому у меня не переделать, я пока не стал. Дело в том, что этот длинный список параметров повторяется много где, и я сделал его генерируемым из мапы (знаки препинания только нужные подставляются где надо - для select одни, для update и insert - другие)
Тут с разбегу не поменяешь на case
Записан

baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #43 : 27-10-2010 09:16 » 

подзапрос тут точно не работает
Опа... А почему?? А какие есть альтернативы?
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #44 : 27-10-2010 09:17 » 

В данном случае - никаких, видимо.

Добавлено через 2 минуты и 32 секунды:
ладно, я думаю, что данный этап - это предел, дальше уже особо не соптимизируешь ЭТО )))
Посмотрим на реакцию пользователей. Если не будут жаловаться, пущай так бегает
« Последнее редактирование: 27-10-2010 09:19 от Алексей1153 » Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #45 : 27-10-2010 10:09 » 

Если нет подзапроса, есть ли временные таблицы или поддержка динамического SQL?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #46 : 27-10-2010 10:16 » 

>>временные таблицы
не знаю, как проверить ?

>>динамического SQL
- я же правильно понимаю, что это запрос, который вызывается не внутри встроенной процедуры, а из внешней программы? Такое есть, конечно
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #47 : 27-10-2010 10:51 » 

Цитата: Алексей1153++
не знаю, как проверить ?
Временная таблица - это таблица, существующая в контексте хранимой процедуры или транзакции и удаляющаяся после завершения всех действий. С точки зрения СУБД по реализации может несколько отличаться от обычной таблицы - с учётом её временного характера существования (минимизируются дисковые операции, всякие анализы статистик и т.п.). Одна и та же таблица (с тем же именем) существует в виде разных экземпляров для каждой сессии пользователя, запуска транзакции, хранимой процедуры (т.е. данные разных контекстов изолируются).

Если нет подзапросов, но они в каком-то конкретном случае были бы очень полезны, можно использовать временные таблицы для хранения результатов подзапросов, т.е. большой запрос с подзапросами (функцию) разложить на последовательность подзапросов (процедуру).

Например, где-то нужно из таблицы с ~1M записей получить выборку ~100 записей. И для всяких расчётов этот подзапрос нужно сделать 2 или более раз в рамках одного большого запроса. В таком случае временная таблица, кэширующая 100 записей, радикально повышает производительность. Оптимизаторы не всегда хорошо с этим справляются, а у FB, наверно, и оптимизаторы посредственные.

Общее правило: как можно раньше по ходу выполнения запроса (или серии запросов) отсекать все ненужные данные.

Цитата: Алексей1153++
я же правильно понимаю, что это запрос, который вызывается не внутри встроенной процедуры, а из внешней программы? Такое есть, конечно
Наверно ты имеешь в виду embedded SQL. Динамический SQL - это когда SQL запрос записывается в переменную строкового типа и потом исполняется. Если в хранимой процедуре нужно делать разноплановые запросы, сильно зависящие от параметров, бывает удобно написать код, конструирующий запрос, адаптированный под конкретные нужды, нежели пытаться в одном большом и универсальном запросе учесть все ньюансы.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #48 : 27-10-2010 11:17 » 

Dimka, ну, FB умеет читать запрос из файла, но сильно сомневаюсь, что тут будет космическая скорость

а количество записей у меня, к сожалению, выбирается не 100, а обычно от нескольких сотен тысяч до несколько миллионов (настраивается под резвость машины)
Записан

baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #49 : 27-10-2010 11:20 » 

Алексей1153++, если не поддерживаются подзапросы (%плохое слово%!), то можно использовать View?
И рассматривался ли вопрос об обновлении FireBird до, хотя бы, версии 2?
« Последнее редактирование: 27-10-2010 11:22 от baldr » Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #50 : 27-10-2010 15:32 » 

Код:
то можно использовать View?
я не знаю. Как это определить ?

Обновление очень геморно, гораздо геморнее возни с оптимизацией. Поэтому не рассматривается )) Если уж придётся что-то такое провораыивать, это будет MySQL, а не птица уже
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #51 : 27-10-2010 17:22 » 

baldr, если твой пример для MySQL, то у тебя есть некритичная ошибка: собаками предваряются только переменные сессии и глобальные для всего сервера (типа переменных окружения). Локальные переменные процедур объявляются через DECLARE и не имеют префиксов.

подзапрос тут точно не работает

Опа... А почему?? А какие есть альтернативы?

Без подзапросов чаще всего можно обойтись (ведь работали же с MySQL 3.23 много лет и не страдали). Внутреннее или внешнее объединение поможет.
В редких случаях - как сказал Димка - через временные таблицы.
Еще реже - через несколько запросов и перенос результатов через переменные.
« Последнее редактирование: 27-10-2010 19:21 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #52 : 27-10-2010 18:49 » 

да, можно организовать "подзапрос" в процедуре так:
Код:
CREATE PROCEDURE PR
returns(
   a integer
  ,b integer
  ,c integer
)
as
begin
 for
   select a from T where ... into :a
 do
   for
     select b,c  from T where a=:a into :b,:c
   do
   begin
     suspend;--вертаем очередную запись в результате работы процедуры
   end;
end;
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #53 : 27-10-2010 19:23 » new

Леш, если пример не совсем абстрактный, то смысла в двух запросах нет: "a = :a" - просто переносим WHERE из первого запроса во второй.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #54 : 27-10-2010 19:57 » 

абстрактный. Вместо многоточия перед where ещё что-то может быть
Записан

Страниц: 1 [2]  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines