Apakah kolom yang tidak relevan memengaruhi waktu kueri pernyataan pilihan?

10

Saya hanya penasaran.

Katakanlah Anda memiliki tabel 1 juta catatan / baris.

select order_value from store.orders

Apakah itu membuat perbedaan apakah tabel itu memiliki 1 bidang, 2 bidang, atau 100 bidang, dalam waktu permintaan aktual? Maksud saya semua bidang selain "order_value."

Saat ini saya sedang mendorong data ke gudang data. Kadang-kadang saya membuang bidang ke tabel yang "dapat digunakan di masa depan, suatu hari nanti" - tetapi mereka tidak ditanyai saat ini, oleh apa pun. Apakah bidang 'asing' ini memengaruhi pernyataan pilih yang tidak menyertakannya, secara langsung atau tidak langsung (tidak * maksud saya)?

pengguna45867
sumber
Ada banyak informasi tentang ini tersedia di web. Kuncinya adalah mendapatkan info terbaru saat teknologi berubah. Apa yang Anda minta sangat tergantung pada pengaturan khusus Anda sehingga tidak mungkin memberikan jawaban yang sangat baik. Poin utama yang perlu diingat adalah bahwa ketika kita beralih ke SSD, banyak hal yang dulunya sangat penting bagi kinerja tidak lagi menjadi masalah.
Joe

Jawaban:

10

Ini sangat tergantung pada indeks dan tipe data.

Menggunakan database Stack Overflow sebagai contoh, seperti inilah tabel Users:

GILA

Ini memiliki PK / CX pada kolom Id. Jadi keseluruhan data tabel diurutkan berdasarkan Id.

Dengan itu sebagai satu-satunya indeks, SQL harus membaca semuanya (tanpa kolom LOB) ke dalam memori jika belum ada di sana.

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SET STATISTICS TIME, IO ON 

SELECT u.Id
INTO  #crap1
FROM dbo.Users AS u

Waktu statistik dan profil io terlihat seperti ini:

Table 'Users'. Scan count 7, logical reads 80846, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2406 ms,  elapsed time = 446 ms.

Jika saya menambahkan indeks nonclustered tambahan pada Id saja

CREATE INDEX ix_whatever ON dbo.Users (Id)

Saya sekarang memiliki indeks yang jauh lebih kecil yang memenuhi permintaan saya.

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SELECT u.Id
INTO  #crap2
FROM dbo.Users AS u

Profil di sini:

Table 'Users'. Scan count 7, logical reads 6587, physical reads 0, read-ahead reads 6549, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2344 ms,  elapsed time = 384 ms.

Kami dapat melakukan lebih sedikit pembacaan dan menghemat sedikit waktu CPU.

Tanpa informasi lebih lanjut tentang definisi tabel Anda, saya tidak bisa benar-benar mencoba mereproduksi apa yang Anda coba ukur lebih baik.

Tetapi Anda mengatakan bahwa kecuali ada indeks spesifik pada kolom tunggal itu, kolom / bidang lain juga akan dipindai? Apakah ini hanya kelemahan yang melekat pada desain tabel rowstore? Mengapa bidang yang tidak relevan dipindai?

Ya, ini khusus untuk tabel rowstore. Data disimpan oleh baris pada halaman data. Bahkan jika data lain pada halaman tersebut tidak relevan dengan permintaan Anda, seluruh baris> halaman> indeks tersebut harus dibaca ke dalam memori. Saya tidak akan mengatakan bahwa kolom lainnya "dipindai" sebanyak halaman yang ada di dalamnya dipindai untuk mengambil nilai tunggal yang relevan dengan kueri.

Menggunakan contoh buku telepon ol: bahkan jika Anda hanya membaca nomor telepon, ketika Anda membalik halaman, Anda mengubah nama belakang, nama depan, alamat, dll bersama dengan nomor telepon.

Erik Darling
sumber
@ jpmc26 Bisa lebih buruk dari itu, karena jika kolom yang diminta adalah bagian dari indeks, kueri dapat dilayani hanya dengan melihat indeks. Jika kolom tidak diindeks, mereka dapat menyebabkan catatan utama dimuat, dan bahkan catatan sekunder untuk jenis tabel / kolom non-custered.
Christopher Schultz
12

Itu tergantung, pada struktur tabel dan indeks yang tersedia.

  • Kasus A: Tabel umum (baris toko), tidak ada indeks aktif (order_value).

    Satu-satunya rencana pelaksanaan yang mungkin adalah membaca seluruh tabel (yang tentu saja jauh berbeda ketika itu 2 vs 200 kolom, jadi beberapa vs beberapa ribu byte lebar).

  • Kasus B: Tabel umum, ada indeks pada (order_value)atau beberapa indeks lain yang menyertakan kolom itu.

    Ada rencana yang lebih baik sekarang, pindai seluruh indeks (salah satunya) - yang tentu saja jauh lebih sempit daripada seluruh tabel, hanya beberapa byte. Yang membuat tidak relevan jika tabel memiliki 2 atau 200 kolom. Hanya indeks yang dipindai.

  • Kasus C: Ini adalah tabel kolom toko.

    Seperti namanya, struktur tabel ini berorientasi pada kolom, bukan pada baris. Tidak perlu indeks apa pun, desain tabel itu sendiri cocok untuk membaca seluruh kolom.

ypercubeᵀᴹ
sumber
Pengetahuan saya agak hijau tentang masalah ini. Ini paling konvensional (misalnya database SQL Server khas) untuk memiliki tabel rowstore, benar? Mengapa seluruh tabel dipindai jika hanya satu kolom / bidang yang perlu dikembalikan? Apakah ini hanya melekat pada desain tabel rowstore?
user45867
@ user45867 ya, data disimpan dalam baris (kecuali beberapa kolom yang sangat besar yang disimpan di luar). Ketika SQL Server membaca dari disk, itu membaca di seluruh blok, ia tidak bisa membaca hanya bagian yang memiliki satu kolom.
ypercubeᵀᴹ