С Новым годом! Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
1 / 1 / 0
Регистрация: 12.07.2018
Сообщений: 19

Оптимизация запроса

24.10.2018, 08:27. Показов 559. Ответов 5

Студворк — интернет-сервис помощи студентам
Добрый день, имеется БД с числом записей в raspis_service примерно 50 записей, во всех остальных таблицах число записей больше 500 000.
Имеются кластеризованные индексы по уникальным идентификаторам.
И следующий запрос:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
WITH ts AS (SELECT TAP_SERVICE.*
            FROM TAP_SERVICE
                JOIN TAP ON TAP_SERVICE.TAP_ID = TAP.TAP_ID
                JOIN Raspis_Service ON Raspis_Service.Raspis_Service_ID=TAP_SERVICE.SERVICE_IN
            WHERE 1=1 
                AND IDSP!=70
                AND FINSOURCE=0
                AND CODE IS NOT NULL
                AND CODE NOT LIKE 'A04.2%'
                AND DATE_OUT<='2018-10-31'
                AND DATE_OUT>='2018-10-01'
                AND tap_service.PODR=3)
 
SELECT rtrim(rs.Code)+' '+rs.Service_name, d1.cnt, d1.cnt * rs.OMC_Price FROM Raspis_Service rs
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE rs.Raspis_Service_ID=SERVICE_IN AND DATE_OUT='2018-10-01') d1
WHERE d1.cnt!=0
Вопросы:
1) Какие некластеризованные индексы можно использовать (по каким полям)?
2) Как можно оптимизировать время выполнения запроса без применения некластеризованных индексов?
приведен пример для 1-го дня, если добавить OUTER APPLY для каждого дня, то время выполнения запроса около 40 секунд и это только для одного подразделения(podr). А для всех подразделений время выполнения занимает минуты 4, что очень долго.
Насколько я понимаю, наибольшее время занимает привязка(проверка) rs.Raspis_Service_ID=SERVICE_IN
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.10.2018, 08:27
Ответы с готовыми решениями:

Оптимизация запроса
На клиентской части данный запрос отрабатывает больше минуты. Как его оптимизировать: select distinct *, ...

Оптимизация запроса
Добрый день, подскажите, пожалуйста: Имеется таблица с данными пользователей: CREATE TABLE Users ( UserID uniqueidentifier NOT NULL...

Оптимизация запроса
Добрый день, уважаемые форумчане. Возникла потребности оптимизировать по производительности некоторые куски своего запроса. Так,...

5
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
24.10.2018, 12:07
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT rtrim(rs.Code)+' '+rs.Service_name, DATE_OUT, count(*), count(*) * rs.OMC_Price
            FROM TAP_SERVICE ts
                JOIN TAP ON ts.TAP_ID = TAP.TAP_ID
                JOIN Raspis_Service rs ON rs.Raspis_Service_ID=ts.SERVICE_IN
            WHERE 1=1 
                AND IDSP!=70
                AND FINSOURCE=0
                AND CODE IS NOT NULL
                AND CODE NOT LIKE 'A04.2%'
                AND DATE_OUT<='2018-10-31'
                AND DATE_OUT>='2018-10-01'
                AND tap_service.PODR=3
            group by
             rs.Code, rs.Service_name, rs.OMC_Price, DATE_OUT
1
1 / 1 / 0
Регистрация: 12.07.2018
Сообщений: 19
24.10.2018, 12:45  [ТС]
Видимо не совсем правильно сформулировал вопрос.
Надо на каждый день рассчитывать, т.е. после rtrim(rs.Code)+' '+rs.Service_name должен быть столбец на каждый день.

т.е. в приведенном мной запросе должно быть:
SQL
1
2
3
4
OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE rs.Raspis_Service_ID=SERVICE_IN AND DATE_OUT='2018-10-01') d1
OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE rs.Raspis_Service_ID=SERVICE_IN AND DATE_OUT='2018-10-02') d2
...
OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE rs.Raspis_Service_ID=SERVICE_IN AND DATE_OUT='2018-10-31') d31
т.е. для каждого столбца должно быть свое условие.
Но спасибо, за вариант.

Добавлено через 6 минут
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
WITH ts AS (SELECT TAP_SERVICE.*
            FROM TAP_SERVICE
                JOIN TAP ON TAP_SERVICE.TAP_ID = TAP.TAP_ID
                JOIN Raspis_Service ON Raspis_Service_ID=SERVICE_IN
            WHERE 1=1 
                AND IDSP!=70
                AND FINSOURCE=0
                AND CODE IS NOT NULL
                AND CODE NOT LIKE 'A04.2%'
                AND DATE_OUT<='2018-10-31'
                AND DATE_OUT>='2018-10-01'
                AND tap_service.PODR=2)
 
SELECT rtrim(rs.Code)+' '+rs.Service_name, d1.cnt "1", d2.cnt "2", d3.cnt "3", d4.cnt "4", d5.cnt "5", d6.cnt "6", d7.cnt "7", d8.cnt "8", d9.cnt "9", d10.cnt "10", 
        d11.cnt "11", d12.cnt "12", d13.cnt "13", d14.cnt "14", d15.cnt "15", d16.cnt "16", d17.cnt "17", d18.cnt "18", d19.cnt "19", d20.cnt "20", 
        d21.cnt, d22.cnt, d23.cnt, d24.cnt, d25.cnt, d26.cnt, d27.cnt, d28.cnt, d29.cnt, d30.cnt "30", oms.cnt, rs.OMC_Price, oms.cnt * rs.OMC_Price FROM Raspis_Service rs
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-01') d1
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-02') d2
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-03') d3
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-04') d4
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-05') d5
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-06') d6
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-07') d7
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-08') d8
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-09') d9
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-10') d10
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-11') d11
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-12') d12
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-13') d13
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-14') d14
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-15') d15
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-16') d16
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-17') d17
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-18') d18
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-19') d19
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-20') d20
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-21') d21
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-22') d22
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-23') d23
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-24') d24
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-25') d25
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-26') d26
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-27') d27
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-28') d28
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-29') d29
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT='2018-10-30') d30
    OUTER APPLY (SELECT COUNT(1) cnt FROM ts WHERE SERVICE_IN = rs.Raspis_Service_ID AND DATE_OUT<='2018-10-31' AND DATE_OUT>='2018-10-01') oms
WHERE oms.cnt!=0
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
24.10.2018, 12:46
Цитата Сообщение от DenisSM1993 Посмотреть сообщение
должен быть столбец на каждый день
На каждый день чего? Как Raspis_Service связано с "каждым днем"?
Из вашего запроса невозможно понять какие столбцы из каких таблиц.

В общем случае, задачи "на каждый день" решаются с помощью служебной таблицы с календарем.
0
1 / 1 / 0
Регистрация: 12.07.2018
Сообщений: 19
24.10.2018, 13:47  [ТС]
На каждый день месяца, выбранного в диапазоне двух дат (диапазон дат не более 31, но может быть любой, для примера: 25.09.2018-20.10.2018).
Суть запроса такая: в with select выбираются все услуги, оказанные в указанный промежуток времени(date_out) для определенного подразделения(podr), с источником финансирования (finsource).
далее выбираются те коды услуг(rs.Code), которые оказывались в указанный день и ведется подсчет, сколько их было оказано. И так для каждого дня.
Отвечает за это OUTER APPLY, где Raspis_service - справочник услуг, связан он столбцом Raspis_Service_id с таблицей Tap_service (Данные, которые мы уже отобрали в with select) полем Service_In. И это видно из запроса.

Что к чему относится:
TAP_SERVICE.TAP_ID
Tap_service.SERVICE_IN
Tap_service.Date_out
TAP.TAP_ID
Tap.idsp
Tap.Finsource
Tap_service.Podr
Raspis_service.Raspis_Service_ID
Rapis_service.Code
Raspis_service.Service_name
Raspis_service.OMS_Price

Другие столбцы не используются

Результат примерно такой:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
Услуга_________________   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
A11.20.027 ЭКО: Пункция   6   0   6   4   0   11  1   6   0   4   5   0   17  0   5
A11.20.030 ЭКО: Перенос крио  0   5   0   1   1   0   0   0   2   0   3   3   0   0   0
A11.20.017 ЭКО: Перенос свежих  4   0   4   2   0   7   0   5   0   3   5   0   11  0   4
A11.20.019 ЭКО: Стимуляция 10  0   7   0   7   0   0   16  0   11  0   8   0   0   12
A11.20.031 ЭКО: Криоконсервация   2   0   3   0   0   6   0   1   1   3   0   0   9   0   1
5 КСГ ЭКО неп: Стим    0   0   0   0   0   0   0   0   0   0   0   0   0   0   1
5 КСГ ЭКО неп: Стим + Пунк 1   0   0   2   0   0   1   1   0   0   0   0   1   0   0
5 КСГ ЭКО полн    4   0   3   2   0   5   0   3   0   1   5   0   7   0   4
5 КСГ ЭКО полн + Крио 0   0   1   0   0   2   0   1   1   2   0   0   4   0   0
5 КСГ ЭКО для Крио 2   0   2   0   0   4   0   0   0   1   0   0   4   0   2
5 КСГ ЭКО: Криоперенос 0   5   0   1   1   0   0   0   2   0   3   3   0   0   0
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
24.10.2018, 14:05
Так на "каждый день календаря" или "на каждый день, имеющийся в данных"?
Если первое, то какие значения должны быть в строках с днями, которых нет в данных.
Если второе, то ответ был дан.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.10.2018, 14:05
Помогаю со студенческими работами здесь

Оптимизация запроса
Подскажите, возможно ли в данном случае оптимизировать сам запрос. Красота и идеологические аспекты не интересуют, только скорость...

Оптимизация запроса
/*Таблица документов*/ Declare @Documents Table( orID int, repID int, DocTypeID int, repIDD nvarchar(100), Condition int ...

Оптимизация запроса
Есть ли возможность существенно сократить время запроса? Не обязательно выжимать последние капли скорости, но сокращение времени запроса...

Оптимизация SQL запроса
есть запрос select ... тут поля ( select field1, field2, (field1/field2) as res from (Select DISTINCT count(1) as...

Оптимизация запроса. Вложенные запросы
Здравствуйте! Подскажите пожалуйста, можно ли оптимизировать скрипт: INSERT INTO ServiceTeam(ProcessListeners, ContactId,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru