Rangkaian Operasi Fisik: Apakah itu menjamin urutan eksekusi?

12

Dalam SQL standar, hasil dari a union alltidak dijamin dalam urutan apa pun. Jadi, sesuatu seperti:

select 'A' as c union all select 'B'

Dapat mengembalikan dua baris dalam urutan apa pun (meskipun, dalam praktiknya pada basis data apa pun yang saya tahu, 'A' akan muncul sebelum 'B').

Dalam SQL Server, ini berubah menjadi rencana eksekusi menggunakan operasi fisik "concatenation".

Saya dapat dengan mudah membayangkan bahwa operasi gabungan akan memindai inputnya, mengembalikan input apa pun yang memiliki catatan yang tersedia. Namun, saya menemukan pernyataan berikut di web (di sini ):

Prosesor Permintaan akan menjalankan rencana ini dalam urutan bahwa operator muncul dalam rencana, yang pertama adalah yang teratas dan yang terakhir adalah yang terakhir.

Pertanyaan: Apakah ini benar dalam praktik? Apakah ini dijamin benar?

Saya belum menemukan referensi dalam dokumentasi Microsoft bahwa input dipindai secara berurutan, dari yang pertama hingga yang terakhir. Di sisi lain, setiap kali saya mencoba menjalankannya, hasilnya menunjukkan bahwa input memang diproses secara berurutan.

Apakah ada cara untuk memiliki proses mesin lebih dari satu input sekaligus? Pengujian saya (menggunakan ekspresi yang jauh lebih rumit daripada konstanta) berada pada mesin 8-core yang diaktifkan paralel, dan sebagian besar pertanyaan memang memanfaatkan paralelisme.

Gordon Linoff
sumber

Jawaban:

10

Tidak , tidak ada dokumentasi dari Microsoft yang menjamin perilaku tersebut, oleh karena itu tidak dijamin .

Selain itu, dengan asumsi bahwa artikel Simple Talk benar, dan bahwa operator fisik Rangkaian selalu memproses input dalam urutan yang ditunjukkan dalam paket (sangat mungkin benar), maka tanpa jaminan bahwa SQL Server akan selalu menghasilkan paket yang tetap sama urutan antara teks kueri dan rencana kueri, Anda hanya sedikit lebih baik.

Kita bisa menyelidiki ini lebih jauh. Jika pengoptimal kueri dapat menyusun ulang input operator Rangkaian, harus ada baris di DMV tidak berdokumen, sys.dm_exec_query_transformation_statssesuai dengan optimasi itu.

SELECT * FROM sys.dm_exec_query_transformation_stats 
    WHERE name LIKE '%CON%' OR name LIKE '%UNIA%'

Pada SQL Server 2012 Enterprise Edition, ini menghasilkan 24 baris. Mengabaikan kecocokan yang salah untuk transformasi yang terkait dengan konstanta, ada satu transformasi yang terkait dengan Operator Fisik Rangkaian UNIAtoCON(Gabungan Semua ke Rangkaian). Jadi, pada tingkat operator fisik, nampak bahwa setelah operator gabungan dipilih, ia akan diproses dalam urutan logis dari semua operator asal.


Sebenarnya itu tidak sepenuhnya benar. Ada penulisan ulang pasca-optimasi yang dapat menyusun ulang input ke operator Concatenation fisik setelah optimasi berbasis biaya selesai. Salah satu contoh terjadi ketika Rangkaian dikenakan sasaran baris (jadi mungkin penting untuk membaca dari input yang lebih murah terlebih dahulu). Lihat UNION ALLOptimasi oleh Paul White untuk lebih jelasnya.

Menulis ulang fisik yang terlambat itu berfungsi hingga dan termasuk SQL Server 2008 R2, tetapi regresi berarti tidak lagi diterapkan ke SQL Server 2012 dan yang lebih baru. Sebuah memperbaiki telah diterbitkan bahwa reinstates menulis ulang ini untuk SQL Server 2014 dan kemudian (tidak 2012) dengan permintaan perbaikan terbaru optimizer diaktifkan (misalnya jejak bendera 4199).


Tetapi tentang operator Logical Union All ( UNIA)? Ada UNIAReorderInputstransformasi, yang dapat menyusun ulang input. Ada juga dua operator fisik yang dapat digunakan untuk mengimplementasikan Union All logis, UNIAtoCONdan UNIAtoMERGE(Union All to Merge Union).

Karenanya, tampaknya pengoptimal kueri dapat menyusun ulang input untuk UNION ALL; Namun, itu tampaknya tidak menjadi transformasi umum (nol penggunaan UNIAReorderInputspada SQL Server saya sudah dapat diakses. Kita tidak tahu keadaan yang akan membuat pengoptimal menggunakan UNIAReorderInputs, meskipun itu pasti digunakan ketika panduan rencana atau penggunaan petunjuk rencana digunakan untuk memaksa rencana yang dibuat menggunakan input baris fisik yang disusun ulang yang disebutkan di atas.

Apakah ada cara untuk memiliki proses mesin lebih dari satu input sekaligus?

Operator fisik Rangkaian dapat ada dalam bagian paralel dari suatu rencana. Dengan sedikit kesulitan, saya dapat membuat rencana dengan rangkaian paralel menggunakan kueri berikut:

SELECT userid, regdate  FROM (  --Users table is around 3mil rows
    SELECT  userid, RegDate FROM users WHERE userid > 1000000
    UNION 
    SELECT  userid, RegDate FROM users WHERE userid < 1000000
    UNION all
    SELECT userid, RegDate FROM users WHERE userid < 2000000
    ) d ORDER BY RegDate OPTION (RECOMPILE)

Jadi, dalam arti yang paling ketat, operator Concatenation fisik tampaknya selalu memproses input secara konsisten (yang teratas pertama, kedua bawah); namun, pengoptimal dapat mengalihkan urutan input sebelum memilih operator fisik, atau menggunakan gabungan Gilda bukannya Rangkaian.

StrayCatDBA
sumber
8

Menurut Craig Freedman , urutan eksekusi untuk operator gabungan dijamin.

Dari posting blognya Melihat Rencana Kueri di Blog MSDN:

Perhatikan bahwa ketika seorang operator memiliki lebih dari satu anak, urutan anak-anak itu penting. Anak paling atas adalah anak pertama sedangkan anak paling bawah adalah anak kedua. Operator gabungan memproses anak-anak dalam urutan ini.

Dan dari buku-buku online Showplan Referensi Logical and Physical Operator

Operator fisik Concatenation memiliki dua input atau lebih dan satu output. Gabungan menyalin baris dari aliran input pertama ke aliran output, lalu mengulangi operasi ini untuk setiap aliran input tambahan.

Mikael Eriksson
sumber
Kutipan itu cukup dekat dengan apa yang saya cari. Saya bersedia mengambil lompatan dari eksekusi agar dikembalikan ke urutan itu - meskipun mengecewakan bahwa dokumentasi menghalangi pemrosesan paralel dalam kasus ini.
Gordon Linoff
2

Jawaban wiki komunitas :

Saya tidak tahu apakah Anda dapat membuktikan bahwa perilaku yang diamati selalu dijamin, dengan satu atau lain cara, kecuali Anda dapat membuat contoh tandingan. Dengan tidak adanya itu, cara untuk memperbaiki urutan hasil yang dikembalikan, tentu saja, adalah dengan menambahkan ORDER BY.

Saya tidak tahu apakah ada "perbaikan", atau bahwa ada kebutuhan untuk perbaikan, jika Anda dapat menunjukkan bahwa dalam beberapa skenario kueri diproses dalam urutan yang berbeda.

Tidak adanya dokumentasi resmi dan eksplisit yang menunjukkan kepada saya bahwa Anda tidak harus bergantung pada ini. Ini persis jenis hal yang membuat orang dalam masalah dengan ORDER BYpandangan, dan GROUP BYtanpa ORDER BY, 8 tahun yang lalu ketika pengoptimal SQL Server 2005 dirilis.

Dengan semua fitur baru di versi SQL Server yang lebih baru (dengan lebih banyak datang), bahkan jika Anda pikir Anda dapat menjamin perilaku tertentu hari ini, saya tidak akan berharap itu berlaku (sampai didokumentasikan untuk melakukannya).

Bahkan jika Anda tidak bergantung pada perilaku ini, apa yang akan Anda lakukan dengan hasilnya? Lagi pula, saya tidak akan menyebut artikel Simple Talk oleh pejabat luar . Yang kami tahu ini hanya dugaan berdasarkan pengamatan.

Microsoft tidak akan pernah menerbitkan dokumentasi resmi yang mengatakan 'x' tidak dijamin untuk melakukan 'y'. Ini adalah salah satu alasan kita masih, hampir satu dekade kemudian, memiliki masalah meyakinkan orang-orang bahwa mereka tidak dapat mengandalkan pesanan yang diamati tanpa ORDER BY- tidak ada dokumentasi yang menyatakan "itu tidak dijamin."

user126897
sumber