-
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
Все правильно (результат), но не нравится вообще.. мастер класс никто не желает дать? :)
-
Время исполнения в сабже - имеется ввиду критично именно оно
-
первое что "в голову пришло".. 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]
-
не то скопировал.. 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]
-
не понимаю >> 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
-
Так вы про версию ничего не сказали, with это CTE, т.е. сервер 2005 и более, а у вас 2000? И вторая таблица поменяла наименование .. и наверное живет не в тойже базе.. а где данных больше в COLLECT_RESULT или во второй? если в первой то можно попробовать поменять их местами, по крайней мере производительность не упадет, а может и вырасти. Ну и планы смотреть.
-
-
да 2000, вторая таблица - да, не в этой БД, название - опять да, сократил, для меньшего загромождения. Данных намного больше в COLLECT_RESULT. в плане Remote Query - 62% времени
> Кщд (27.07.11 18:13) [6]
спасибо, смотрю
хотя сейчас подсунул в работу - уже приемлимая скорость
-
>SQLEXPRESS (28.07.11 08:30) [7] как минимум надо избежать повторного чтения COLLECT_RESULT - оно просто ни к чему также нужно помнить, что самая тяжелая операция в БД - это объединение таблиц соответственно, нужно проверить варианты с exists(in)
-
> join COLLECT_RESULT CR on CR.PHONE = C.PHONE and CR.DATE_TIME > = C.MAX_DT
Есть индекс на поле DATE_TIME?
-
>Loginov Dmitry © (28.07.11 11:40) [9]
>SQLEXPRESS (27.07.11 16:36) >все три поля - первичный ключ
да и не нужен отдельный индекс по DATE_TIME в данном случае
-
Имхо, в данном случае лишним не будет.
-
>Loginov Dmitry © (28.07.11 12:01) [11] зачем?
-
> зачем?
С целью минимизации времени поиска. Условие "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" ???
-
нет, всегда Clustered Index Scan показывает. Завтра с утра подпихну > "бабушкин трюк" думаю, однако, это не очень требуется, уже довольно шустро, если только для морального удовлетворения
> Будет ли для MS SQL разница между PK > 1) "PHONE, CALL_RESULT, DATE_TIME" > 2) "PHONE, DATE_TIME, CALL_RESULT"
будет, по-идее
-
>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, селективность которого в данном запросе сомнительна
-
>SQLEXPRESS (28.07.11 16:44) [14] >если только для морального удовлетворения дело Ваше с точки зрения логики, доп. соединение с COLLECT_RESULT - избыточно а в случае, если COLLECT_RESULT - миллионник - убыточно
|