全部产品
Search
文档中心

PolarDB:Gunakan Semijoins untuk Mempercepat Query Paralel

更新时间:Jul 06, 2025

Anda dapat menggunakan semijoins untuk mengoptimalkan subquery, mengurangi jumlah query, dan meningkatkan kinerja query. Topik ini menjelaskan dasar-dasar semijoins serta cara menggunakannya dalam query paralel.

Prasyarat

Cluster Anda adalah PolarDB for MySQL 8.0 dengan versi revisi yang memenuhi salah satu persyaratan berikut:

  • 8.0.1.0.5 atau yang lebih baru.

  • 8.0.2.2.7 atau yang lebih baru.

Untuk informasi tentang cara melihat versi cluster, lihat bagian Query versi engine dari topik "Versi engine".

Informasi Latar Belakang

Mulai MySQL 5.6.5, semijoins didukung. Sebuah semijoin mengembalikan baris dari tabel luar jika baris tersebut cocok dengan setidaknya satu baris di tabel dalam. Jika baris di tabel luar cocok dengan beberapa baris di tabel dalam, semijoin hanya mengembalikan baris tersebut sekali. Dalam query yang berisi subquery tanpa semijoins, subquery dievaluasi untuk setiap tuple yang sesuai dengan kondisi di tabel luar, sehingga menurunkan efisiensi query. Dengan semijoins, subquery diubah menjadi join, dan tabel dalam ditarik ke query luar. Hal ini memungkinkan tabel dalam dan luar diproses secara paralel. Setelah sistem menemukan kecocokan antara kedua tabel, hasil langsung dikembalikan, meningkatkan efisiensi query secara signifikan.

1

Strategi

Berikut adalah strategi semijoin yang digunakan:

  • Strategi Penghapusan Duplikat

    Strategi Penghapusan Duplikat bekerja dengan membuat tabel sementara dan menggunakan ID baris unik untuk mencegah duplikat.

    2

  • Strategi Materialisasi

    Strategi Materialisasi bekerja dengan mematerialisasi tabel bersarang menjadi tabel sementara terindeks. Tabel sementara ini digunakan untuk melakukan join, dengan indeks yang membantu menghapus duplikat dan mendukung pencarian saat menggabungkan tabel sementara dengan tabel luar.

    3

  • Strategi FirstMatch

    Strategi FirstMatch bekerja dengan mengeksekusi subquery dan memotong jalur eksekusinya segera setelah kecocokan pertama ditemukan untuk mencegah produksi duplikat.

    4

  • Strategi LooseScan

    Strategi LooseScan bekerja dengan mengelompokkan data di tabel dalam berdasarkan indeks, memilih satu catatan dari setiap grup nilai subquery, dan menggabungkan catatan tersebut dengan tabel luar untuk menghasilkan hasil query tanpa duplikat.

    5

Sintaksis

Secara umum, semijoin menggunakan klausa IN atau EXISTS sebagai kondisi join.

  • IN

    SELECT * FROM Employee WHERE DeptName IN (   SELECT DeptName   FROM Dept )
  • EXISTS

    SELECT * FROM Employee WHERE EXISTS (   SELECT 1   FROM Dept   WHERE Employee.DeptName = Dept.DeptName )

Jalankan semijoins secara paralel untuk meningkatkan kinerja

PolarDB mendukung semua strategi semijoin dan mempercepat query paralel yang menggunakan strategi semijoin. Setiap tugas semijoin dibagi menjadi beberapa subtugas yang dijalankan secara paralel menggunakan model multi-threading. Mulai PolarDB 8.0.2.2.7, query paralel multi-fase untuk materialisasi semijoin didukung, meningkatkan kinerja query semijoin lebih lanjut. Contoh berikut menggunakan Q20.

SELECT
   s_name,
   s_address 
FROM
   supplier,
   nation 
WHERE
   s_suppkey IN 
   (
      SELECT
         ps_suppkey 
      FROM
         partsupp 
      WHERE
         ps_partkey IN 
         (
            SELECT
               p_partkey 
            FROM
               part 
            WHERE
               p_name LIKE '[COLOR]%' 
         )
         AND ps_availqty > ( 
         SELECT
            0.5 * SUM(l_quantity) 
         FROM
            lineitem 
         WHERE
            l_partkey = ps_partkey 
            AND l_suppkey = ps_suppkey 
            AND l_shipdate >= date('[DATE]') 
            AND l_shipdate < date('[DATE]') + interval '1' year ) 
   )
   AND s_nationkey = n_nationkey 
   AND n_name = '[NATION]' 
ORDER BY
   s_name;

Dalam contoh ini, baik subquery maupun query luar merupakan query paralel dengan DOP 32. Subquery pertama kali menghasilkan tabel materialisasi secara paralel, kemudian query luar diproses secara paralel. Hal ini sepenuhnya memanfaatkan kemampuan pemrosesan CPU dan memaksimalkan potensi query paralel. Contoh ini menunjukkan kemampuan query paralel multi-fase setelah fitur query paralel elastis diaktifkan dalam skenario data panas TPC-H standar dengan skala 100 GB.

Catatan

Uji kinerja TPC-H yang dijelaskan dalam topik ini diimplementasikan berdasarkan uji benchmark TPC-H tetapi tidak memenuhi semua persyaratan uji benchmark TPC-H. Oleh karena itu, hasil pengujian tidak dapat dibandingkan dengan hasil publikasi uji benchmark TPC-H.

Berikut adalah rencana eksekusi query paralel elastis:

 -> Sort: <temporary>.s_name  (cost=5014616.15 rows=100942)
    -> Stream results
        -> Nested loop inner join  (cost=127689.96 rows=100942)
            -> Gather (slice: 2; workers: 64; nodes: 2)  (cost=6187.68 rows=100928)
                -> Nested loop inner join  (cost=1052.43 rows=1577)
                    -> Filter: (nation.N_NAME = 'KENYA')  (cost=2.29 rows=3)
                        -> Table scan on nation  (cost=2.29 rows=25)
                    -> Parallel index lookup on supplier using SUPPLIER_FK1 (S_NATIONKEY=nation.N_NATIONKEY), with index condition: (supplier.S_SUPPKEY is not null), with parallel partitions: 863  (cost=381.79 rows=631)
            -> Single-row index lookup on <subquery2> using <auto_distinct_key> (ps_suppkey=supplier.S_SUPPKEY)
                -> Materialize with deduplication
                    -> Gather (slice: 1; workers: 64; nodes: 2)  (cost=487376.70 rows=8142336)
                        -> Nested loop inner join  (cost=73888.70 rows=127224)
                            -> Filter: (part.P_NAME like 'lime%')  (cost=31271.54 rows=33159)
                                -> Parallel table scan on part, with parallel partitions: 6244  (cost=31271.54 rows=298459)
                            -> Filter: (partsupp.PS_AVAILQTY > (select #4))  (cost=0.94 rows=4)
                                -> Index lookup on partsupp using PRIMARY (PS_PARTKEY=part.P_PARTKEY)  (cost=0.94 rows=4)
                                -> Select #4 (subquery in condition; dependent)
                                    -> Aggregate: sum(lineitem.L_QUANTITY)
                                        -> Filter: ((lineitem.L_SHIPDATE >= DATE'1994-01-01') and (lineitem.L_SHIPDATE < <cache>((DATE'1994-01-01' + interval '1' year))))  (cost=4.05 rows=1)
                                            -> Index lookup on lineitem using LINEITEM_FK2 (L_PARTKEY=partsupp.PS_PARTKEY, L_SUPPKEY=partsupp.PS_SUPPKEY)  (cost=4.05 rows=7)

Waktu eksekusi ketika query paralel elastis multi-node diaktifkan adalah:

456789

Hasilnya menunjukkan bahwa waktu eksekusi berkurang dari 43,52 detik menjadi 2,29 detik, dengan kecepatan query meningkat hingga 19 kali lebih cepat.