如何強制SQL走性能更優的hash join

来源:https://www.cnblogs.com/huaweiyun/archive/2023/10/13/17761544.html
-Advertisement-
Play Games

本文分享自華為雲社區《【SQL優化】為什麼有時候無法走執行性能更優的hashjoin》,作者: leapdb。 1. hash join通常優於nestloop join 通常nestloop join的複雜度是O(N方),hash join時間複雜度是O(N),所以我們一般傾向於使用hash jo ...


本文分享自華為雲社區《【SQL優化】為什麼有時候無法走執行性能更優的hashjoin》,作者: leapdb。

1. hash join通常優於nestloop join

通常nestloop join的複雜度是O(N方),hash join時間複雜度是O(N),所以我們一般傾向於使用hash join。   在SQL腳本調優過程中通常有兩種方式,強制走hash join方式:

1. 在session級關閉nestloop方式,set enable_nestloop to off;

2. 在SQL中通過 /*+ hashjoin(a b) */ 方式,讓a和b表走hash join;  
CREATE DATABASE test_td WITH DBCOMPATIBILITY='td';

create table dim_day(day_code char(8));
create table dwr_rpo as select current_date - 1 as day_code; --返回了date類型

test_td=# \d+ dwr_rpo
                       Table "public.dwr_rpo"
  Column  | Type | Modifiers | Storage | Stats target | Description 
----------+------+-----------+---------+--------------+-------------
 day_code | date |           | plain   |              | 
Has OIDs: no
Distribute By: ROUND ROBIN
Location Nodes: ALL DATANODES
Options: orientation=row, compression=no

explain select *
from dwr_rpo a
left join dim_day c
on c.day_code = a.day_code;

id |                  operation                   | E-rows  | E-distinct | E-memory | E-width |   E-costs    
---+----------------------------------------------+---------+------------+----------+---------+--------------
 1 | ->  Streaming (type: GATHER)                 | 1310148 |            |          |    1694 | 279235196.70 
 2 |    ->  Nested Loop Left Join (3, 4)          | 1310148 |            | 1MB      |    1694 | 279229682.93 
 3 |       ->  Seq Scan on dwr_rpo a              | 1310148 |            | 1MB      |    1676 | 46589.16     
 4 |       ->  Materialize                        |  109575 |            | 16MB     |      22 | 3747.76      
 5 |          ->  Streaming(type: BROADCAST)      |  109575 |            | 2MB      |      22 | 3565.14      
 6 |             ->  Seq Scan on dim_day c        |   36525 |            | 1MB      |      22 | 272.75       

               Predicate Information (identified by plan id)                
-----------------------------------------------------------------------------
  2 --Nested Loop Left Join (3, 4)
        Join Filter: ((c.day_code)::timestamp without time zone = a.day_code)

mermaid-diagram-2023-09-06-114052.png

可是,以上SQL無論用哪種方式都走不上hash join。我們需要看一下,join兩端的數據類型是否支持hash比較。   1. 為什麼有時候無法走執行性能更優的hashjoin

不同數據類型計算hash函數不同,互不相容的數據類型無法進行hash比較。

2. 為什麼hashjoin秒級,nestloop需要兩個小時

nestloop複雜度:131w * 10w = 1310億

hashjoin複雜度:131w

所以兩種方式性能差距很大。   3. 為什麼有類型轉換,還不能hash join

看似類型相近,但由於兩端的精度,格式,有無時區等不一樣,無法認為直接相等。

4. 都哪些數據類型間的join不支持hash?
select oprname,oprkind,oprcanhash,
  (select typname from pg_type where oid=oprleft) oprleft,
  (select typname from pg_type where oid=oprright) oprright 
from pg_operator 
where oprname='=' and oprcanhash='f';

 oprname | oprkind | oprcanhash |    oprleft    |   oprright    
---------+---------+------------+---------------+---------------
 =       | b       | f          | xid           | int8
 =       | b       | f          | xid32         | int4
 =       | b       | f          | tid           | tid
 =       | b       | f          | box           | box
 =       | b       | f          | path          | path
 =       | b       | f          | tinterval     | tinterval
 =       | b       | f          | money         | money
 =       | b       | f          | circle        | circle
 =       | b       | f          | lseg          | lseg
 =       | b       | f          | line          | line
 =       | b       | f          | bit           | bit
 =       | b       | f          | varbit        | varbit
 =       | b       | f          | date          | timestamp
 =       | b       | f          | date          | timestamptz
 =       | b       | f          | timestamp     | date
 =       | b       | f          | timestamptz   | date
 =       | b       | f          | timestamp     | timestamptz
 =       | b       | f          | timestamptz   | timestamp
 =       | b       | f          | tsvector      | tsvector
 =       | b       | f          | tsquery       | tsquery
 =       | b       | f          | record        | record
 =       | b       | f          | hll           | hll
 =       | b       | f          | hll_hashval   | hll_hashval
 =       | b       | f          | roaringbitmap | roaringbitmap
(24 rows)
  主要是timestamp, timestamptz, date間互相join是無法走hash。其它數據類型不常見。   開發建議:join兩端的數據類型儘量一致或互相相容。   5. 為什麼 oracle 相容模式沒有問題,td相容模式有問題?

current_date 在TD相容模式下為date類型;

current_date 在Oracle相容模式下為timestamp類型;

點擊關註,第一時間瞭解華為雲新鮮技術~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • <工作記錄——Report> 報表前的數據獲取操作是高重覆性的,今天差不多完成了腳本,下述是代碼: 1 // See https://aka.ms/new-console-template for more information 2 using System.IO; 3 using System. ...
  • 目錄一、微處理器與匯流排1.微處理器的概述1.1 運算器1.2 控制器1.2.1 指令控制1.2.2 時序控制1.2.3 操作控制二、8086/8088微處理器1.8086/8088CPU的指令特點1.1 指令流水線1.2 記憶體的分段管理技術1.3 支持多處理器系統2.8088/8086的外部引腳及其 ...
  • 本腳本通過域管下發預設為root許可權執行 #!/bin/bash cd /home #快捷方式圖標名稱 string_imgName="temp1.png" #快捷方式文件名稱 string_fileName="/changePassword.desktop" #快捷方式內容 function in ...
  • Tcpdump 抓包工具使用以及Wireshark解析pacp包 參考鏈接(比較詳細):https://blog.csdn.net/weixin_42866036/article/details/128004750 1.項目上數據在共用時,由於介面有Token鑒權動作,有時調用介面會出現鑒權失效問題 ...
  • 前言 存儲引擎都是把數據存儲在文件系統上,通過通過查詢命令,可以查看數據目錄所在的本機路徑。 mysql> SHOW VARIABLES LIKE 'datadir'; + + + | Variable_name | Value | + + + | datadir | /var/lib/mysql/ ...
  • Trino是一款開源的高性能、分散式SQL查詢引擎,專門用於對各種異構數據源運行互動式分析查詢,支持從GB到PB的數據量範圍。 ...
  • 解決SUM函數返回為NULL SUM函數的作用:計算某一欄位中所有行的數值和, 使用SUM函數進行對符合條件的結果行數進行求和。 問題產生: sum 求和時會對 null 進行過濾,不計算,但如果沒有返回結果,則sum 函數的返回值為 null,不是 0: 解決方式: 1. IFNULL 使用IFN ...
  • 在DBS-集群列表-更多-連接查詢-死鎖中,看到9月22日有資料庫死鎖日誌,後排查發現是因為mysql的優化-index merge(索引合併)導致資料庫死鎖。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...