2 / 2 / 1
Регистрация: 16.04.2022
Сообщений: 1,032

Долгий запрос

31.07.2024, 22:36. Показов 680. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Есть одна большая таблица test.myTable3 (не нормализованная) и две маленькие tempTable1 и tempTable2. Идет соединение с группировкой.

Имеется такой запрос.
Кликните здесь для просмотра всего текста
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
49
50
51
52
53
EXPLAIN(analyze,buffers)
SELECT
    t1."column4",
    t1."column3",
    t2."column1",
    t2."column2",
    SUM(t1."column26") AS "column26",
    t1."column25",
    t1."column38",
    CASE WHEN t1."column37" = 'aaaa' THEN 'aaa' ELSE 'aaaaaa' END,
    t1."column24",
    t3."column2",
    t1."column35"
FROM
    test.myTable3 t1
LEFT JOIN
    tempTable1 t2
ON
    LOWER(t1."column49") = LOWER(t1."column49")
    AND
    LOWER(t1."column50") = LOWER(t1."column50")
LEFT JOIN
    tempTable2 t3
ON
    LOWER(t1."column37") = LOWER(t3."column1")
WHERE
    NOT(
        t3."column3" IS NULL
        AND
        t3."column4" IS NULL
    )
    AND
    t1."column3" = 'aaaa'
    AND
    t1."column58" = 2024 --Не статичное условие
    AND
    t1."column4" >= 202001
    AND
    t1."column9" = 'CCCC'
    AND
    t1."column30" = 'bbbbbbbb bbbbbbb' --not t1."column30" = 'aaaaaaa aaaaaaaa'
GROUP BY 
    t1."column4",
    t1."column3",
    t3."column2",
    t2."column1",
    t2."column2",
    t1."column38",
    t1."column24",
    t1."column25",
    t1."column35",
    CASE WHEN t1."column37" = 'aaaa' THEN 'aaa' ELSE 'aaaaaa' END--t1."column37" 
;

Для эксперимента пока созданы два индекса для большой таблицы. Для маленьких таблиц индексы не создавались.
SQL
1
2
3
4
5
6
7
8
CREATE INDEX myTable3_idx2 ON test.myTable3 USING btree 
("column58", (CASE WHEN "column37" = 'aaaa' THEN 'aaa' ELSE 'aaaaaa' END),(LOWER("column37")), (LOWER("column49")),(LOWER("column50")))
WHERE "column3" = 'aaaa' AND "column4" > 202001 AND "column9" = 'CCCC' AND  "column30" = 'bbbbbbbb bbbbbbb';
 
CREATE INDEX myTable3_idx3 ON test.myTable3 USING btree 
("column3", "column4", "column24", "column25", "column35", "column38", "column58", (CASE WHEN "column37" = 'aaaa' THEN 'aaa' ELSE 'aaaaaa' END),
(LOWER("column37")), (LOWER("column49")), (LOWER("column50")))
WHERE "column9" = 'CCCC' AND "column30" = 'bbbbbbbb bbbbbbb';
План запроса
Кликните здесь для просмотра всего текста
Code
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
GroupAggregate  (cost=13482790.42..13615059.31 rows=3112209 width=1318) (actual time=469057.807..490824.767 rows=70200 loops=1)
  Group Key: t1.column4, t3.column2, t2.column1, t2.column2, t1.column38, t1.column24, t1.column25, t1.column35, (CASE WHEN ((t1.column37)::text = 'aaaa'::text) THEN 'aaa'::text ELSE 'aaaaaa'::text END)
  Buffers: shared read=947721, local hit=3, temp read=109780 written=109789
  ->  Sort  (cost=13482790.42..13490570.95 rows=3112209 width=1293) (actual time=469057.467..483885.877 rows=8845200 loops=1)
        Sort Key: t1.column4, t3.column2, t2.column1, t2.column2, t1.column38, t1.column24, t1.column25, t1.column35, (CASE WHEN ((t1.column37)::text = 'aaaa'::text) THEN 'aaa'::text ELSE 'aaaaaa'::text END)
        Sort Method: external merge  Disk: 878240kB
        Buffers: shared read=947721, local hit=3, temp read=109780 written=109789
        ->  Nested Loop Left Join  (cost=320052.61..12018818.60 rows=3112209 width=1293) (actual time=4564.129..392971.570 rows=8845200 loops=1)
              Join Filter: ((lower((t1.column49)::text) = lower((t1.column49)::text)) AND (lower((t1.column50)::text) = lower((t1.column50)::text)))
              Buffers: shared read=947721, local hit=3
              ->  Hash Join  (cost=320052.61..2596594.47 rows=3112209 width=601) (actual time=4564.094..354800.123 rows=8845200 loops=1)
                    Hash Cond: (lower((t1.column37)::text) = lower((t3.column1)::text))
                    Buffers: shared read=947721, local hit=2
                    ->  Bitmap Heap Scan on mytable3 t1  (cost=320041.03..2509885.64 rows=8892027 width=85) (actual time=4563.680..319267.330 rows=8845200 loops=1)
                          Recheck Cond: (((column3)::text = 'aaaa'::text) AND (column4 >= 202001) AND (column58 = 2024) AND ((column9)::text = 'CCCC'::text) AND ((column30)::text = 'bbbbbbbb bbbbbbb'::text))
                          Heap Blocks: exact=813257
                          Buffers: shared read=947721
                          ->  Bitmap Index Scan on mytable3_idx3  (cost=0.00..317818.03 rows=8892027 width=0) (actual time=4238.606..4238.606 rows=8845200 loops=1)
                                Index Cond: (((column3)::text = 'aaaa'::text) AND (column4 >= 202001) AND (column58 = 2024))
                                Buffers: shared read=134464
                    ->  Hash  (cost=10.70..10.70 rows=70 width=1032) (actual time=0.389..0.390 rows=132 loops=1)
                          Buckets: 1024  Batches: 1  Memory Usage: 16kB
                          Buffers: local hit=2
                          ->  Seq Scan on temptable2 t3  (cost=0.00..10.70 rows=70 width=1032) (actual time=0.030..0.093 rows=132 loops=1)
                                Filter: ((column3 IS NOT NULL) OR (column4 IS NOT NULL))
                                Buffers: local hit=2
              ->  Materialize  (cost=0.00..11.65 rows=110 width=694) (actual time=0.000..0.000 rows=1 loops=8845200)
                    Buffers: local hit=1
                    ->  Seq Scan on temptable1 t2  (cost=0.00..11.10 rows=110 width=694) (actual time=0.022..0.023 rows=1 loops=1)
                          Buffers: local hit=1
Planning:
  Buffers: shared hit=7 read=1 dirtied=2
Planning Time: 83.493 ms
Execution Time: 490934.062 ms

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

Использовать вложенный запрос для большой таблицы нет смысла, потребует много дополнительной памяти.

Скажите, как возможно ускорить? Как правильно нужно написать индекс?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.07.2024, 22:36
Ответы с готовыми решениями:

Долгий DISTINCT
Здравствуйте! Есть большая таблица из 60 столбцов и 1 млрд строк. Есть индекс с составными полями (10 колонок). Когда запускаю...

Долгий запрос
MSSQL-2008. Есть таблица в котором около 4 млн записей. В которой поле DateOper(тип datetime2(7)) проиндексировано. Если делать такой...

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

8
2 / 2 / 1
Регистрация: 16.04.2022
Сообщений: 1,032
01.08.2024, 08:52  [ТС]
Цитата Сообщение от MConst Посмотреть сообщение
После чтения индекса опять сканирует таблицу.
Почему так происходит? Что в индексе неправильно?
0
918 / 291 / 58
Регистрация: 01.06.2023
Сообщений: 816
01.08.2024, 09:00
А зачем два индекса? В таблицу пошел так как нужны были данные которых нет в покрывающем индексе

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

а еще у Вас не верная статистика по таблице temptable1 ожидается 110 строк а пришло 1
0
2 / 2 / 1
Регистрация: 16.04.2022
Сообщений: 1,032
01.08.2024, 10:27  [ТС]
Цитата Сообщение от Swa111 Посмотреть сообщение
В таблицу пошел так как нужны были данные которых нет в покрывающем индексе
А какие это данные, которых нет? Вроде все поля и выражения указал в создании индекса.
0
918 / 291 / 58
Регистрация: 01.06.2023
Сообщений: 816
01.08.2024, 10:54
Колонка 9 и 30
0
2 / 2 / 1
Регистрация: 16.04.2022
Сообщений: 1,032
01.08.2024, 14:54  [ТС]
Цитата Сообщение от MConst Посмотреть сообщение
После чтения индекса опять сканирует таблицу.
Цитата Сообщение от Swa111 Посмотреть сообщение
Колонка 9 и 30
Добавил
SQL
1
2
3
4
5
6
7
CREATE INDEX myTable3_idx4 ON test.myTable3 USING btree 
(
    "column3", "column4", "column9", "column24", "column25", "column30", "column35", "column38", "column58",
    (CASE WHEN "column37" = 'aaaa' THEN 'aaa' ELSE 'aaaaaa' END),
    (LOWER("column37")), (LOWER("column49")), (LOWER("column50"))
) WHERE
    "column3" = 'aaaa' AND "column4" >= 202001 AND "column9" = 'CCCC' AND "column30" = 'bbbbbbbb bbbbbbb';
Запускаю тот же запрос
Кликните здесь для просмотра всего текста
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
49
50
51
52
EXPLAIN(analyze,buffers)
SELECT
    t1."column4",
    t1."column3",
    t2."column1",
    t2."column2",
    SUM(t1."column26") AS "column26",
    t1."column25",
    t1."column38",
    CASE WHEN t1."column37" = 'aaaa' THEN 'aaa' ELSE 'aaaaaa' END,
    t1."column24",
    t3."column2",
    t1."column35"
FROM
    test.myTable3 t1
LEFT JOIN
    tempTable1 t2
ON
    LOWER(t1."column49") = LOWER(t1."column49")
    AND
    LOWER(t1."column50") = LOWER(t1."column50")
LEFT JOIN
    tempTable2 t3
ON
    LOWER(t1."column37") = LOWER(t3."column1")
WHERE
    NOT(
        t3."column3" IS NULL
        AND
        t3."column4" IS NULL
    )
    AND
    t1."column3" = 'aaaa'
    AND
    t1."column58" = 2024 --Не статичное условие
    AND
    t1."column4" >= 202001
    AND
    t1."column9" = 'CCCC'
    AND
    t1."column30" = 'bbbbbbbb bbbbbbb' --not t1."column30" = 'aaaaaaa aaaaaaaa'
GROUP BY 
    t1."column4",
    t1."column3",
    t3."column2",
    t2."column1",
    t2."column2",
    t1."column38",
    t1."column24",
    t1."column25",
    t1."column35",
    CASE WHEN t1."column37" = 'aaaa' THEN 'aaa' ELSE 'aaaaaa' END--t1."column37"

План запроса
Кликните здесь для просмотра всего текста
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
GroupAggregate  (cost=13482790.42..13615059.31 ROWS=3112209 width=1318) (actual TIME=485092.881..506222.652 ROWS=70200 loops=1)
  GROUP KEY: t1.column4, t3.column2, t2.column1, t2.column2, t1.column38, t1.column24, t1.column25, t1.column35, (CASE WHEN ((t1.column37)::text = 'aaaa'::text) THEN 'aaa'::text ELSE 'aaaaaa'::text END)
  Buffers: shared READ=947721, LOCAL hit=3, temp READ=109780 written=109789
  ->  Sort  (cost=13482790.42..13490570.95 ROWS=3112209 width=1293) (actual TIME=485092.584..499882.377 ROWS=8845200 loops=1)
        Sort KEY: t1.column4, t3.column2, t2.column1, t2.column2, t1.column38, t1.column24, t1.column25, t1.column35, (CASE WHEN ((t1.column37)::text = 'aaaa'::text) THEN 'aaa'::text ELSE 'aaaaaa'::text END)
        Sort Method: external MERGE  Disk: 878240kB
        Buffers: shared READ=947721, LOCAL hit=3, temp READ=109780 written=109789
        ->  Nested Loop LEFT JOIN  (cost=320052.61..12018818.60 ROWS=3112209 width=1293) (actual TIME=15573.197..408535.844 ROWS=8845200 loops=1)
              JOIN FILTER: ((LOWER((t1.column49)::text) = LOWER((t1.column49)::text)) AND (LOWER((t1.column50)::text) = LOWER((t1.column50)::text)))
              Buffers: shared READ=947721, LOCAL hit=3
              ->  Hash JOIN  (cost=320052.61..2596594.47 ROWS=3112209 width=601) (actual TIME=15573.147..369965.589 ROWS=8845200 loops=1)
                    Hash Cond: (LOWER((t1.column37)::text) = LOWER((t3.column1)::text))
                    Buffers: shared READ=947721, LOCAL hit=2
                    ->  Bitmap Heap Scan ON mytable3 t1  (cost=320041.03..2509885.64 ROWS=8892027 width=85) (actual TIME=15572.908..333995.660 ROWS=8845200 loops=1)
                          Recheck Cond: (((column3)::text = 'aaaa'::text) AND (column4 >= 202001) AND (column58 = 2024) AND ((column9)::text = 'CCCC'::text) AND ((column30)::text = 'bbbbbbbb bbbbbbb'::text))
                          Heap Blocks: exact=813257
                          Buffers: shared READ=947721
                          ->  Bitmap INDEX Scan ON mytable3_idx3  (cost=0.00..317818.03 ROWS=8892027 width=0) (actual TIME=15238.079..15238.080 ROWS=8845200 loops=1)
                                INDEX Cond: (((column3)::text = 'aaaa'::text) AND (column4 >= 202001) AND (column58 = 2024))
                                Buffers: shared READ=134464
                    ->  Hash  (cost=10.70..10.70 ROWS=70 width=1032) (actual TIME=0.218..0.219 ROWS=132 loops=1)
                          Buckets: 1024  Batches: 1  Memory Usage: 16kB
                          Buffers: LOCAL hit=2
                          ->  Seq Scan ON temptable2 t3  (cost=0.00..10.70 ROWS=70 width=1032) (actual TIME=0.022..0.049 ROWS=132 loops=1)
                                FILTER: ((column3 IS NOT NULL) OR (column4 IS NOT NULL))
                                Buffers: LOCAL hit=2
              ->  Materialize  (cost=0.00..11.65 ROWS=110 width=694) (actual TIME=0.000..0.000 ROWS=1 loops=8845200)
                    Buffers: LOCAL hit=1
                    ->  Seq Scan ON temptable1 t2  (cost=0.00..11.10 ROWS=110 width=694) (actual TIME=0.023..0.023 ROWS=1 loops=1)
                          Buffers: LOCAL hit=1
Planning:
  Buffers: shared hit=54 READ=2 dirtied=4
Planning TIME: 9.813 ms
Execution TIME: 506330.002 ms

Как видим также. И еще вначале использует не индекс myTable3_idx4, а myTable3_idx3.

Кстати, удалил индекс myTable3_idx3 и план запроса использует внчале myTable3_idx4, потом также сканирует таблицу.
0
918 / 291 / 58
Регистрация: 01.06.2023
Сообщений: 816
01.08.2024, 15:17
еще не хватает колонки 26
0
2 / 2 / 1
Регистрация: 16.04.2022
Сообщений: 1,032
01.08.2024, 17:40  [ТС]
Также вначале читает индекс, а потом сканирует таблицу.

Здесь похоже только один вариант - использовать циклы, то есть выгружать частями.
0
918 / 291 / 58
Регистрация: 01.06.2023
Сообщений: 816
02.08.2024, 10:56
SQL
1
2
3
4
5
6
LEFT JOIN
    tempTable1 t2
ON
    LOWER(t1."column49") = LOWER(t1."column49")
    AND
    LOWER(t1."column50") = LOWER(t1."column50")
У Вас ошибка в запросе, в способе соединении нет таблицы t2
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.08.2024, 10:56
Помогаю со студенческими работами здесь

Долгий запрос в SQL
Добрый день! Делаю запрос в БД, объем получаемого списка 38 мБ. время уходит 2 минуты, можно как то ускорить процесс? def zapros(): ...

Долгий update
Доброго дня. Объясните, пожалуйста, где я туплю. Есть вот такой запрос: UPDATE otto_article LEFT JOIN otto_main USING (ItemID)...

Долгий ребилд индексов
Всем привет. У меня есть 1С и сервер MS SQL и идет очень долгий ребилд индексов больше чем один день. В связи с этим я решил набросать...

Долгий коннект к базе
Всем доброго времени суток. Имеется ib 6.0 на Win 2003. Прога, написанная на билдере. 20 юзеров. При коннекте с утра конект идёт около...

MAintenancePlan очень долгий
Долго делается обычный план обслуживания для 1с, который используют везде, на других серверах такой же план выполняется очень быстро. ...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

Новые блоги и статьи
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
Запрет удаления строк ТЧ документа при определённом условии
Maks 19.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "Аккумуляторы", разработанного в конфигурации КА2. У данного документа есть ТЧ, в которой в зависимости от прав доступа. . .
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru