Конференция "Базы" » Ни кто не не желает в SQL размяться? Время исполнения [D7, MSSQL]
 
  • SQLEXPRESS (27.07.11 16:36) [0]
    MSSQL, (ADO, D7, хотя не важно, запрос главное )
    из таблицы COLLECT_RESULT
    [PHONE] [bigint] NOT NULL,  // телефон
    [CALL_RESULT] [int] NOT NULL,  //результат звонка
    [DATE_TIME] [datetime] NOT NULL, // время звонка
    // все три поля - первичный ключ
    выбрать те телефоны которые есть в таблице DL5008 (структура не важна, есть поле Phone01)

    в виде
    Телефон, кол-во звонков всего, время последнего звонка, результат последнего звонка

    написал так.


    select
     C.*, CR.CALL_RESULT
    from
     (select
        A.PHONE, CNT, MAX_DT
      from
        (SELECT
           CR.PHONE, count(*) CNT
         FROM
           DL5008 D
           join COLLECT_RESULT CR on CR.PHONE = D.Phone01
         group by CR.PHONE
         ) B
         join (SELECT
                 CR.PHONE, Max(CR.DATE_TIME) MAX_DT
               FROM
                 DL5008 D
                 join COLLECT_RESULT CR on CR.PHONE = D.Phone01
               group by PHONE
               ) A on A.PHONE = B.PHONE
     ) C
       join COLLECT_RESULT CR on CR.PHONE = C.PHONE and CR.DATE_TIME = C.MAX_DT

    order by PHONE



    Все правильно (результат),
    но не нравится вообще..

    мастер класс никто не желает дать? :)
  • SQLEXPRESS (27.07.11 16:36) [1]
    Время исполнения в сабже  - имеется ввиду критично именно оно
  • b z (27.07.11 17:16) [2]
    первое что "в голову пришло"..
    with CR (PHONE, PCount, PDate) AS
    (
    select С.PHONE, count(С.PHONE), max(C.[DATE_TIME])
    from COLLECT_RESULT C
    join DL5008 D on CR.PHONE = D.Phone01
    [DATE_TIME]=C.DATE_TIME]
    group by С.PHONE
    ) SELECT PHONE, PCount, PDate, C1.CALL_RESULT FROM CR
    join COLLECT_RESULT C on CR.PHONE = C.PHONE AND CR.PDate=C.[DATE_TIME]

  • b z (27.07.11 17:18) [3]
    не то скопировал..
    with CR (PHONE, PCount, PDate) AS
    (
      select С.PHONE, count(С.PHONE), max(C.[DATE_TIME])
      from COLLECT_RESULT C
         join DL5008 D on R.PHONE = D.Phone01
      group by С.PHONE
    ) SELECT PHONE, PCount, PDate, C1.CALL_RESULT FROM CR
    join COLLECT_RESULT C on CR.PHONE = C.PHONE AND CR.PDate=C.[DATE_TIME]

  • SQLEXPRESS (27.07.11 17:52) [4]
    не понимаю >> with CR (PHONE, PCount, PDate) AS
    наверное так?

    select A.*, CR2.CALL_RESULT from
    (
     select CR.PHONE, count(CR.PHONE) CNT, max(CR.DATE_TIME) DT
     from COLLECT_RESULT CR
        join [10.171.0.4].[icm1_baA].dbo.DL_5008_5006 D on CR.PHONE = D.Phone01
     group by CR.PHONE )A
    join COLLECT_RESULT CR2 on CR2.DATE_TIME = A.DT and CR2.PHONE = A.PHONE
  • b z (27.07.11 18:08) [5]
    Так вы про версию ничего не сказали, with это CTE, т.е. сервер 2005 и более, а у вас 2000?
    И вторая таблица поменяла наименование .. и наверное живет не в тойже базе..
    а где данных больше в COLLECT_RESULT или во второй? если в первой то можно попробовать поменять их местами, по крайней мере производительность не упадет, а может и вырасти.
    Ну и планы смотреть.
  • Кщд (27.07.11 18:13) [6]
    >b z   (27.07.11 18:08) [5]
    и чтобы избежать двойного прохода по COLLECT_RESULT, используем "бабушкин трюк": http://www.sql.ru/forum/actualthread.aspx?tid=289314#2627786
  • SQLEXPRESS (28.07.11 08:30) [7]
    да 2000,
    вторая таблица - да, не в этой БД, название - опять да, сократил, для меньшего загромождения.
    Данных намного больше в COLLECT_RESULT.
    в плане Remote Query - 62% времени


    > Кщд   (27.07.11 18:13) [6]

    спасибо, смотрю

    хотя сейчас подсунул в работу - уже приемлимая скорость
  • Кщд (28.07.11 11:31) [8]
    >SQLEXPRESS   (28.07.11 08:30) [7]
    как минимум надо избежать повторного чтения COLLECT_RESULT - оно просто ни к чему
    также нужно помнить, что самая тяжелая операция в БД - это объединение таблиц
    соответственно, нужно проверить варианты с exists(in)
  • Loginov Dmitry © (28.07.11 11:40) [9]

    > join COLLECT_RESULT CR on CR.PHONE = C.PHONE and CR.DATE_TIME
    > = C.MAX_DT


    Есть индекс на поле DATE_TIME?
  • Кщд (28.07.11 11:44) [10]
    >Loginov Dmitry ©   (28.07.11 11:40) [9]

    >SQLEXPRESS   (27.07.11 16:36)  
    >все три поля - первичный ключ

    да и не нужен отдельный индекс по DATE_TIME в данном случае
  • Loginov Dmitry © (28.07.11 12:01) [11]
    Имхо, в данном случае лишним не будет.
  • Кщд (28.07.11 12:45) [12]
    >Loginov Dmitry ©   (28.07.11 12:01) [11]
    зачем?
  • Loginov Dmitry © (28.07.11 15:31) [13]

    > зачем?


    С целью минимизации времени поиска.
    Условие "CR.DATE_TIME = C.MAX_DT" в случае отсутствия индекса по полю DATE_TIME может привести к необходимости FullScan (разумеется среди записей, отобранных по условию CR.PHONE = C.PHONE). Но это лишь мое ИМХО, возможно я ошибаюсь.
    Будет ли для MS SQL разница между PK
    1) "PHONE, CALL_RESULT, DATE_TIME"
    2) "PHONE, DATE_TIME, CALL_RESULT"
    ???
  • SQLEXPRESS (28.07.11 16:44) [14]
    нет, всегда Clustered Index Scan показывает.
    Завтра с утра подпихну
    > "бабушкин трюк"
    думаю, однако, это не очень требуется, уже довольно шустро,
    если только для морального удовлетворения


    > Будет ли для MS SQL разница между PK
    > 1) "PHONE, CALL_RESULT, DATE_TIME"
    > 2) "PHONE, DATE_TIME, CALL_RESULT"

    будет, по-идее
  • Кщд (28.07.11 18:52) [15]
    >Loginov Dmitry ©   (28.07.11 15:31) [13]
    Вы слабо представляете себе, как работает оптимизатор, но это лирика
    а практика в том, что для ТС достаточно простого соединения:

    from COLLECT_RESULT C
    join DL5008 D on CR.PHONE = D.Phone01
    [DATE_TIME]=C.DATE_TIME]
    group by С.PHONE



    и ничего более, включая индекс по DATE_TIME, селективность которого в данном запросе сомнительна
  • Кщд (28.07.11 22:52) [16]
    >SQLEXPRESS   (28.07.11 16:44) [14]
    >если только для морального удовлетворения
    дело Ваше
    с точки зрения логики, доп. соединение с COLLECT_RESULT - избыточно
    а в случае, если COLLECT_RESULT - миллионник - убыточно
 
Конференция "Базы" » Ни кто не не желает в SQL размяться? Время исполнения [D7, MSSQL]
Есть новые Нет новых   [134431   +10][b:0][p:0.002]