Форум программистов, компьютерный форум, киберфорум
PostgreSQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
2 / 2 / 1
Регистрация: 16.04.2022
Сообщений: 1,031

Индекс для not

01.08.2024, 08:27. Показов 569. Ответов 6
Метки нет (Все метки)

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

Провожу эксперименты с индексами.

Есть такие исходные данные
Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE test.myTable4 ("column1" VARCHAR(255), "column2" VARCHAR(480), "column3" INTEGER);
INSERT INTO test.myTable4
SELECT
    "column1", "column2", "column3"
FROM
    (VALUES
        --(null, 'aaaaaaaa', 10)
        ('bbbb', 'bbbbbbbb', 20)
        ,('cccc', 'cccccccc', 30)
        ,('dddd', 'dddddddd', 40)
        ,('eeee', 'eeeeeeee', 50)
    ) t ("column1", "column2", "column3")
CROSS JOIN
    (SELECT pg_catalog.generate_series(1, 1000,1) AS "value") t0
;


Есть sql-запрос, который имеет условие
SQL
1
NOT "column1" = 'bbbb'
Создаем индексы.
SQL
1
2
3
4
5
CREATE INDEX myTable4_idx1 ON test.myTable4 USING btree ("column1");
CREATE INDEX myTable4_idx2 ON test.myTable4 USING btree ("column2") WHERE NOT "column1" = 'bbbb';
 
EXPLAIN(analyze,buffers)
SELECT "column2", SUM("column3") AS "column3" FROM test.myTable4 WHERE NOT "column1" = 'bbbb' GROUP BY "column2";
В плане запросе индексы не используются.

Далее пишем запрос без not и заменяем на <>.
SQL
1
2
3
4
CREATE INDEX myTable4_idx3 ON test.myTable4 USING btree ("column2") WHERE "column1" <> 'bbbb';
 
EXPLAIN(analyze,buffers)
SELECT "column2", SUM("column3") AS "column3" FROM test.myTable4 WHERE "column1" <> 'bbbb' GROUP BY "column2";
Также не используются индексы.

А теперь в запросе перечисляем нужные значения.
SQL
1
2
3
4
5
6
7
8
9
10
CREATE INDEX myTable4_idx4 ON test.myTable4 USING btree ("column2") WHERE "column1" = 'cccc' OR "column1" = 'dddd' OR "column1" = 'eeee';
 
EXPLAIN(analyze,buffers)
SELECT "column2", SUM("column3") AS "column3" FROM test.myTable4 WHERE "column1" = 'cccc' OR "column1" = 'dddd' OR "column1" = 'eeee' GROUP BY "column2";
 
 
CREATE INDEX myTable4_idx5 ON test.myTable4 USING btree ("column2") WHERE "column1" IN ('cccc','dddd','eeee');
 
EXPLAIN(analyze,buffers)
SELECT "column2", SUM("column3") AS "column3" FROM test.myTable4 WHERE "column1" IN ('cccc','dddd','eeee') GROUP BY "column2";
Используется индекс myTable4_idx4.

Но следует учесть, что в документации
Кликните здесь для просмотра всего текста
B-деревья могут работать в условиях на равенство и в проверках диапазонов с данными, которые можно отсортировать в некотором порядке. Точнее, планировщик запросов PostgreSQL может задействовать индекс-B-дерево, когда индексируемый столбец участвует в сравнении с одним из следующих операторов:

< <= = >= >

При обработке конструкций, представимых как сочетание этих операторов, например BETWEEN и IN, так же может выполняться поиск по индексу-B-дереву.


Как видим, что мы не можем использовать условие в индексе для not или <>, но можем использовать другие заданные значения. Но фишка в том, что эти другие заданные значения могут меняться и заранее не узнаешь. Ведь до выгрузки по этим значениям в where нужно задать индекс.

Скажите, какое может быть решение в данном случае?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.08.2024, 08:27
Ответы с готовыми решениями:

В строке первый символ получает индекс 1, последний индекс 2, второй индекс 3, предпоследний индекс 4, третий индекс 5
В строке первый символ получает индекс 1, последний индекс 2, второй индекс 3, предпоследний индекс 4, третий индекс 5 и так далее. Теперь...

Даны целые числа а1, а2,., a индекс (n). Вывести на печать только те числа, для которых а индекс (i) ≥ i
Помогите пожалуйста решить задачу, не получается сделать с индексом (i). Даны целые числа а1, а2,..., a индекс (n). Вывести на печать...

Дано a1,n Вывести на экран n-ый член последовательности a(индекс n)=a(индекс n-1)+2. 2)Дано n. Последовательность задана формулой b(индекс n)=2+(-1)c
Дано a1,n Вывести на экран n-ый член последовательности a(индекс n)=a(индекс n-1)+2. 2)Дано n. Последовательность задана формулой...

6
912 / 286 / 57
Регистрация: 01.06.2023
Сообщений: 810
01.08.2024, 08:46
Все зависит от того сколько записей отсекает этот not. Если будет отсечена большая часть, то по хорошему ввести справочник со всеми значениями

SQL
1
2
3
4
5
6
SELECT
...
FROM
  bigtable
WHERE
  bigtable.Iddic IN (SELECT id FROM dictionarytable WHERE NOT code = "aaaaaa")
не факт что оптимизатору это понравится но попробовать можно

если отсекает меньше половины, то возможно полное сканирование это самый быстрый вариант
0
2 / 2 / 1
Регистрация: 16.04.2022
Сообщений: 1,031
01.08.2024, 10:21  [ТС]
Цитата Сообщение от Swa111 Посмотреть сообщение
Все зависит от того сколько записей отсекает этот not.
Вообще несколько значений, но со временем меняются.

Добавлено через 1 час 32 минуты
Цитата Сообщение от Swa111 Посмотреть сообщение
SQL
1
2
3
4
5
6
SELECT
...
FROM
  bigtable
WHERE
  bigtable.Iddic IN (SELECT id FROM dictionarytable WHERE NOT code = "aaaaaa")
не факт что оптимизатору это понравится но попробовать можно
Ну если так, хотя выглядит как-то изощренно.
Кликните здесь для просмотра всего текста
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
do
$$
DECLARE
    "var_sql" text;
    "var_values" text;
BEGIN
    "var_sql" := 'SELECT string_agg(DISTINCT concat('''''''', "column1", ''''''''), '','') FROM test.myTable4 WHERE "column1" <> ''bbbb'';';
    EXECUTE "var_sql"  INTO "var_values";
    "var_sql" := '
        drop index if exists myTable4_idx6;
        CREATE INDEX myTable4_idx6 ON test.myTable4 USING btree ("column2") where "column1" in (' || "var_values" || ');
    ';
 
    EXECUTE "var_sql";
END;
$$;
 
EXPLAIN(analyze,buffers)
SELECT
    "column2", SUM("column3") AS "column3"
FROM
    test.myTable4 WHERE "column1" IN (SELECT DISTINCT "column1" FROM test.myTable4 WHERE NOT "column1" = 'bbbb')
GROUP BY
    "column2";


План запроса
Кликните здесь для просмотра всего текста
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
HashAggregate  (cost=191.22..191.25 rows=4 width=17) (actual time=7.829..7.833 rows=3 loops=1)
  Group Key: mytable4.column2
  Batches: 1  Memory Usage: 24kB
  Buffers: shared hit=52
  ->  Hash Join  (cost=83.59..171.22 rows=4000 width=13) (actual time=2.778..6.057 rows=3000 loops=1)
        Hash Cond: ((mytable4.column1)::text = (mytable4_1.column1)::text)
        Buffers: shared hit=52
        ->  Seq Scan on mytable4  (cost=0.00..66.00 rows=4000 width=18) (actual time=0.016..0.587 rows=4000 loops=1)
              Buffers: shared hit=26
        ->  Hash  (cost=83.54..83.54 rows=4 width=5) (actual time=2.730..2.731 rows=3 loops=1)
              Buckets: 1024  Batches: 1  Memory Usage: 9kB
              Buffers: shared hit=26
              ->  HashAggregate  (cost=83.50..83.54 rows=4 width=5) (actual time=2.700..2.702 rows=3 loops=1)
                    Group Key: mytable4_1.column1
                    Batches: 1  Memory Usage: 24kB
                    Buffers: shared hit=26
                    ->  Seq Scan on mytable4 mytable4_1  (cost=0.00..76.00 rows=3000 width=5) (actual time=0.010..1.323 rows=3000 loops=1)
                          Filter: ((column1)::text <> 'bbbb'::text)
                          Rows Removed by Filter: 1000
                          Buffers: shared hit=26
Planning:
  Buffers: shared hit=16 read=1
Planning Time: 1.602 ms
Execution Time: 7.903 ms

Индекс все равно не использует.
0
912 / 286 / 57
Регистрация: 01.06.2023
Сообщений: 810
01.08.2024, 10:59
Так и не будет работать индекс должен быть без всяких where просто по колонке 1
0
2 / 2 / 1
Регистрация: 16.04.2022
Сообщений: 1,031
01.08.2024, 15:17  [ТС]
Делаю по другому
Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE TEMPORARY TABLE myTempTable4 ("column1" VARCHAR(255));
INSERT INTO myTempTable4 VALUES ('bbbb');
 
CREATE INDEX myTable4_idx1 ON test.myTable4 USING btree ("column1");
CREATE INDEX myTable4_idx2 ON test.myTable4 USING btree ("column1", "column2");
 
EXPLAIN(analyze,buffers)
SELECT
    t1."column2", SUM(t1."column3") AS "column3"
FROM
    test.myTable4 t1
LEFT JOIN
    myTempTable4 t2
ON
    t1."column1" = t2."column1"
WHERE
    t2."column1" IS NULL
GROUP BY
    t1."column2";

План запроса
Кликните здесь для просмотра всего текста
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
GroupAggregate  (cost=94.39..94.41 rows=1 width=17) (actual time=2.863..3.301 rows=3 loops=1)
  Group Key: t1.column2
  Buffers: shared hit=26, local hit=1
  ->  Sort  (cost=94.39..94.39 rows=1 width=13) (actual time=2.638..2.787 rows=3000 loops=1)
        Sort Key: t1.column2
        Sort Method: quicksort  Memory: 214kB
        Buffers: shared hit=26, local hit=1
        ->  Hash Anti Join  (cost=13.38..94.38 rows=1 width=13) (actual time=0.042..1.314 rows=3000 loops=1)
              Hash Cond: ((t1.column1)::text = (t2.column1)::text)
              Buffers: shared hit=26, local hit=1
              ->  Seq Scan on mytable4 t1  (cost=0.00..66.00 rows=4000 width=18) (actual time=0.019..0.346 rows=4000 loops=1)
                    Buffers: shared hit=26
              ->  Hash  (cost=11.50..11.50 rows=150 width=516) (actual time=0.013..0.014 rows=1 loops=1)
                    Buckets: 1024  Batches: 1  Memory Usage: 9kB
                    Buffers: local hit=1
                    ->  Seq Scan on mytemptable4 t2  (cost=0.00..11.50 rows=150 width=516) (actual time=0.009..0.010 rows=1 loops=1)
                          Buffers: local hit=1
Planning Time: 0.181 ms
Execution Time: 3.340 ms

Индекс не использует.
0
912 / 286 / 57
Регистрация: 01.06.2023
Сообщений: 810
01.08.2024, 15:19
так и не должен.
чем вы руководствовались создавая индекс myTable4_idx2?
0
2 / 2 / 1
Регистрация: 16.04.2022
Сообщений: 1,031
01.08.2024, 15:29  [ТС]
Цитата Сообщение от Swa111 Посмотреть сообщение
чем вы руководствовались создавая индекс myTable4_idx2?
Пока экспериментирую.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.08.2024, 15:29
Помогаю со студенческими работами здесь

Запись в Memo( индекс - это индекс кнопки, на которую нажали) числа 1
Мне нужно записать в Memo с индексом таким же, какой и у кнопки, которую только что нажали, только на 1 меньше (-1), записать 1. Вот я...

Индекс за пределами диапазона. Индекс должен быть положительным числом
Дратути молодые люди, подскажите как решить: System.ArgumentOutOfRangeException: &quot;Индекс за пределами диапазона. Индекс должен быть...

Среднее арифметическое, индекс минимального, индекс максимального элемента массива
Помогите переделать для Visual Studio c# Form Нужно чтоб код работал благодаря кнопки Буду очень благодарна за помощь) const int...

Хеш-таблица, метод цепочек, первичный индекс и вторичный индекс
Добрый вечер! Пытаюсь написать программу, которая будет работать как хеш-таблица. Для вычисления первичного индекса используется символьный...

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


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru