Rumah  >  Artikel  >  Tutorial sistem  >  Optimumkan pertanyaan SQL untuk mengurangkan masa jalan 'Tidak dalam'

Optimumkan pertanyaan SQL untuk mengurangkan masa jalan 'Tidak dalam'

PHPz
PHPzke hadapan
2024-01-13 20:12:051051semak imbas
Pengenalan Dalam persekitaran pangkalan data yang dioptimumkan oleh DBA, kebanyakan masalah prestasi sebenarnya disebabkan oleh penulisan SQL yang tidak betul. Dunia SQL penuh dengan keajaiban Hari ini kita akan melihat SQL pembunuh yang akan membuatkan anda ingin muntah darah.

Untuk pelanggan insurans, ETL mengambil masa beberapa jam Kami membuat laporan SQL dan mendapati bahawa tekanan adalah terutamanya pada salah satu SQL.

耗时数小时,‘Not in’ SQL 优化

Masa pelaksanaan tunggal: 5788 (saat)

Bacaan logik tunggal: 1 bilion (blok)

Bilangan baris yang dikembalikan pada satu masa: 210,000 (baris)

Mari kita lihat kenyataan SQL dahulu Kerana ia agak panjang, kami hanya memetik sebahagian daripadanya di sini

耗时数小时,‘Not in’ SQL 优化

Lihat pelan pelaksanaannya:

耗时数小时,‘Not in’ SQL 优化

Kami memberi tumpuan terutamanya pada baris 7 hingga 16: kami mendapati terdapat dua imbasan jadual penuh. Penapis telah dilakukan di tengah.

Pengalaman bertahun-tahun memberitahu saya bahawa Penapis yang terdiri daripada dua imbasan jadual penuh mempunyai masalah yang serius kerana ia melibatkan pemprosesan data satu demi satu. Dalam pelan pelaksanaan ini, jadual didorong masih diimbas secara keseluruhannya.

Operasi Tidak Dalam/Dalam kadangkala menghasilkan operasi Penapis Dalam versi sebelum 11g, penyataan tidak dalam mesti ditukar menjadi anti-cantum dalam penyata Limit, jika tidak, anda hanya boleh menggunakan Penapis untuk menapis satu persatu.

Mari kita berikan contoh:

SQL1:BUAT T_OBJ JADUAL SEBAGAI ID_OBJEK PILIH,PEMILIK,NAMA_OBJEK,JENIS_OBJEK DARIPADA DBA_OBJECTS DI MANA PEMILIK != 'SEROL';SQL2 ASPILIH_NAMA, DATA_JENIS OBJEK MANA OWNER!='SEROL ' ;
Lihat sifat T_OBJ:

耗时数小时,‘Not in’ SQL 优化

Didapati bahawa tiada sekatan tidak batal pada tiga lajur.

Kami berpura-pura menjadi pengoptimum 10G pada masa ini.

SQL> set alter session optimizer_features_enable=”10.2.0.5″;

Laksanakan SQL berikut:

SQL> set autotracetrace exp

SQL> PILIH * DARI T_TABLE DI MANA JADUAL_NAME TIDAK MASUK(PILIH OBJECT_NAME DARI T_OBJ);

Melihat pelan pelaksanaan pada masa ini, kami mendapati penapis digunakan:

耗时数小时,‘Not in’ SQL 优化

Tetapi dalam versi 11g, pengoptimum secara automatik boleh menukar Tidak beroperasi daripada Penapis mahal kepada Null-Aware-Anti-Join.

Jika anda menambah syarat Bukan nol atau menetapkan atribut medan kepada bukan nol

SQL> ubah jadual T_OBJ ubah suai(OBJECT_NAME BUKAN NULL);

Lakukan kenyataan yang sama sekali lagi:

SQL> PILIH * DARI T_TABLE DI MANA TABLE_NAME

TIDAK MASUK(PILIH OBJECT_NAME DARI T_OBJ

WHEREOBJECT_NAME BUKAN NULL);

Lihat pelan pelaksanaan sekali lagi:

耗时数小时,‘Not in’ SQL 优化

Pada masa ini kami mendapati bahawa dalam rancangan pelaksanaan, hash sertai anti.

Dan, dalam 11g, tidak dalam lajur dibenarkan tanpa sekatan tidak batal, dan Anti-Join juga boleh ditukar.

SQL> set alter session optimizer_features_enable=”11.2.0.4″;

SQL> ubah jadual T_OBJ ubah suai(OBJECT_NAME NULL);

SQ> PILIH * DARI T_TABLE DI MANA MEJA_NAME

TIDAK MASUK (PILIH_NAMA_OBJEK DARI T_OBJ);

Lihat pelan pelaksanaan:

耗时数小时,‘Not in’ SQL 优化

Kami melihat bahawa pada masa ini, hash join anti.

juga digunakan tanpa sekatan yang tidak kosong.

Ciri ini boleh dikawal melalui parameter pengoptimum.

SQL>ubah set sesi “_optimizer_null_aware_antijoin”=SALAH;

Laksanakan kenyataan di atas sekali lagi dan lihat pelan pelaksanaan:

SQL> PILIH * DARI T_TABLE DI MANA TABLE_NAME

TIDAK MASUK (PILIH_NAMA_OBJEK DARI T_OBJ);

耗时数小时,‘Not in’ SQL 优化

Saya dapati saya masih menggunakan hash join anti.

Telah disahkan bahawa ia tidak menjadi masalah dengan tetapan parameter ini

Logik

Not in ialah pengecualian bersama antara set hasil Sebenarnya, terdapat banyak cara untuk menulis semula, seperti:

—Tidak wujud

— Sambungan Luar + adalah batal

—Tolak

Perbezaan antara

not in dan tiga cara penulisan di atas ialah: not in akan mengecualikan nilai nol.

Kami cuba menulis semula.

耗时数小时,‘Not in’ SQL 优化

Kemudian apabila anda fikir keajaiban akan berlaku, kenyataan itu melaporkan ralat!

耗时数小时,‘Not in’ SQL 优化

Mengapa ralat dilaporkan?

Jika kita menukar kenyataan ini kepada bukan dalam:

耗时数小时,‘Not in’ SQL 优化

Mengikut logik tidak masuk, 'A.' perlu ditambah sebelum kod_bayaran pada masa ini, ini tidak menjadi masalah, tetapi jika anda melihat kenyataan ini lagi, ia akan menjadi:

耗时数小时,‘Not in’ SQL 优化

Memandangkan tiada medan FEE_CODE dalam TMP_APP_xxx_PREM A, Not in tidak boleh ditukar secara automatik kepada Null Aware ANTI JOIN.

Jadi, kini jawapannya terbongkar, ternyata satu kesilapan? ! Saya meneka permulaan, tetapi tidak berakhir.

Tetapi dalam kes ini, kerana tiada pernyataan eksplisit dalam pernyataan SQL, ralat ini tidak pernah ditemui semasa proses analisis awal.

Adakah anda juga tidak berkata-kata? Sebenarnya, apa yang saya ingin tanyakan lagi, adakah anda sering menulis SQL pembunuh Tetapi tidak mengapa jika anda sakit, saya ada ubat. (Muka tidak bersalah, jangan pukul saya)

Kita semua tahu bahawa dalam persekitaran pangkalan data yang dioptimumkan oleh DBA, sebahagian besar masalah prestasi sebenarnya disebabkan oleh penulisan SQL yang tidak betul.

Untuk sistem yang tidak dalam talian, melalui audit dan kawalan SQL awal, 80% masalah SQL akan dihapuskan dalam peringkat tunas Bagi sistem berjalan dalam talian, masalah prestasi yang berpotensi boleh ditemui dan diselesaikan untuk mengelakkannya dalam tunas.

Audit SQL membolehkan DBA berubah daripada doktor kecemasan sistem kepada doktor penjagaan kesihatan sistem

1 DBA mengambil bahagian dalam pembangunan kod aplikasi dan proses ujian: Sediakan pembangun dengan cadangan pembangunan pangkalan data profesional dan pengoptimuman

2 Optimumkan bahagian hadapan: Reka bentuk SQL dan indeks yang cekap mengikut keperluan perniagaan sebelum kod aplikasi masuk dalam talian

3. Kawal risiko perubahan: Pra-nilai kesan perubahan struktur jadual dan perubahan SQL semasa pembangunan aplikasi pada aplikasi yang sedang dijalankan, dan tentukan tetingkap perubahan yang sesuai dan pelan perubahan.

Atas ialah kandungan terperinci Optimumkan pertanyaan SQL untuk mengurangkan masa jalan 'Tidak dalam'. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:linuxprobe.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam