Как заставить SQL использовать хеш-соединение с большей производительностью

Эта статья опубликована сообществом Huawei Cloud « [Оптимизация SQL] Почему иногда невозможно использовать hashjoin с более высокой производительностью выполнения », автор: jumpdb.

1. Хэш-соединение обычно лучше, чем соединение с помощью Nestloop.

Обычно сложность соединения вложенным циклом составляет O(N в квадрате), а временная сложность хеш-соединения равна O(N), поэтому мы обычно склонны использовать хеш-соединение.
 
В процессе настройки SQL-скрипта обычно существует два способа принудительного использования метода хэш-соединения:

1. Выключите режим Nestloop на уровне сеанса, установите для Enable_nestloop значение Off;

2. Используйте метод /*+ hashjoin(ab) */ в SQL для хеширования таблиц a и b;
 
СОЗДАТЬ БАЗУ ДАННЫХ test_td С DBCOMPATIBILITY='td'; 

создать таблицу dim_day(day_code char(8)); 
создать таблицу dwr_rpo как select current_date - 1 как day_code; --返回了date类型

test_td=# \d+ dwr_rpo Столбец 
                       таблицы "public.dwr_rpo" 
  | Тип | Модификаторы | Хранение | Цель статистики | Описание 
----------+------+-----------+---------+--------- -----+------------- 
 код дня | дата | | простой | | 
Имеет OID: нет. 
Распределить по: КРУГОВОЙ ПОРЯДОК Узлы 
местоположения: ВСЕ ДАТАНОДЫ 
Опции: ориентация = строка, сжатие = нет 

объяснения, выберите * 
из dwr_rpo 
левое соединение dim_day c 
на c.day_code = a.day_code; 

идентификатор | операция | Электронные строки | Электронный отчетливый | Электронная память | E-ширина | Электронные расходы     
---+------------------------------------------- ---+---------+------------+----------+---------+-- ------------ 
 1 | -> Потоковая передача (тип: СОБИРАТЬ) | 1310148 | | | 1694 | 279235196,70 
 2 | -> Вложенный цикл левого соединения (3, 4) | 1310148 | | 1 МБ | 1694 | 279229682,93 
 3 | -> Seq Scan на dwr_rpo a | 1310148 | | 1 МБ | 1676 | 46589,16      
 4 | -> Материализовать | 109575 | | 16 МБ | 22 | 3747,76       
 5 | -> Потоковая передача (тип: ВЕЩАНИЕ) | 109575 | | 2 МБ | 22 | 3565,14       
 6 | -> Seq Scan в dim_day c | 36525 | | 1 МБ | 22 | 272.75        

               Информация о предикате (идентифицируется по идентификатору плана)                 
----------------------------------------- ------------------------------------ 
  2 --Вложенный цикл Левое соединение (3, 4) 
        Фильтр соединения : ((c.day_code)::timestamp без часового пояса = a.day_code)

русалка-диаграмма-2023-09-06-114052.png

Однако приведенный выше SQL не может обеспечить хеш-соединение независимо от того, какой метод используется. Нам нужно проверить, поддерживают ли типы данных на обоих концах соединения сравнение хешей.
 
 
1. Почему иногда невозможно использовать hashjoin с большей производительностью?

Разные типы данных имеют разные функции вычисления хеш-функций, и сравнения хэш-функций не могут выполняться для взаимно несовместимых типов данных.

 
2. Почему хеш-соединение занимает секунды, а Nestloop — два часа?

сложность гнездового цикла: 131w * 10w = 131 миллиард

Сложность хеш-соединения: 131 Вт.

Таким образом, между этими двумя методами существует большой разрыв в производительности.
 
3. Почему не получается хеш-соединение, хотя есть преобразование типов?

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

4. Какие типы данных не поддерживают хеширование в соединениях?
выберите имя_опра,oprkind,oprcanhash, 
  (выберите имя_типа из pg_type, где oid=oprleft) oprleft, 
  (выберите имя_типа из pg_type, где oid=oprright) oprright 
из pg_operator 
, где oprname='=' и oprcanhash='f'; 

 имя | опркинд | опрканхэш | опрлевый | правильно     
---------+---------+------------+---------------+ --------------- 
 = | б | ж | сид | int8 
 = | б | ж | xid32 | int4 
 = | б | ж | время | время 
 = | б | ж | коробка | коробка 
 = | б | ж | путь | путь 
 = | б | ж | интервал | интервал 
 = | б | ж | деньги | деньги 
 = | б | ж | круг | круг 
 = | б | ж | лсег | лсег 
 = | б | ж | линия | линия 
 = | б | ж | немного | бит 
 = | б | ж | варбит | варбит 
 = | б | ж | дата | временная метка 
 = | б | ж | дата | временная метка 
 = | б | ж | временная метка | дата 
 = | б | ж | временная метка | дата 
 = | б | ж | временная метка | временная метка 
 = | б | ж | временная метка | временная метка 
 = | б | ж | цвектор | цвектор 
 = | б | ж | цвери | цкери 
 = | б | ж | запись | запись 
 = | б | ж | хл | хл 
 = | б | ж | hll_hashval | hll_hashval 
 = | б | ж | ревущий битмап | ревущий битмап 
(24 строки)
 
Основная причина заключается в том, что временная метка, временная метка и дата не могут быть хешированы путем соединения друг с другом. Другие типы данных встречаются реже.
 
Предложение по развитию: типы данных на обоих концах соединения должны быть максимально согласованными или совместимыми друг с другом.
 
5. Почему с режимом совместимости oracle нет проблем, но есть проблема с режимом совместимости td?

current_date — тип даты в режиме совместимости с TD;

current_date имеет тип отметки времени в режиме совместимости с Oracle;

 

Нажмите, чтобы подписаться и узнать о новых технологиях Huawei Cloud как можно скорее~

Автор открытого фреймворка NanUI перешёл на продажу стали, и проект был приостановлен.Список бесплатных бесплатных приложений номер один в Apple App Store занимает порнографическое ПО TypeScript.Он только стал популярным, почему большие парни начинают от него отказываться ? Октябрьский список TIOBE: Наибольший спад в Java, C# приближается к выпуску Java Rust 1.73.0 Мужчину подтолкнула его подруга-ИИ к убийству королевы Англии, и он был приговорен к девяти годам тюремного заключения Qt 6.6 официально выпущен Reuters: RISC-V Технология становится ключом к китайско-американской технологической войне Новое поле битвы RISC-V: Lenovo не контролируется какой-либо отдельной компанией или страной и планирует выпустить ПК на базе Android
{{o.name}}
{{м.имя}}

рекомендация

отmy.oschina.net/u/4526289/blog/10117402