Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Bagaimana sql server mengurutkan data Anda?

Meskipun baik untuk bertanya-tanya tentang bagaimana hal itu dapat dijelaskan bahwa Anda sering melihat urutan yang sama, saya ingin menunjukkan bahwa tidak pernah merupakan ide yang baik untuk mengandalkan urutan implisit yang disebabkan oleh implementasi tertentu dari mesin database yang mendasarinya. Dengan kata lain, senang mengetahui alasannya, tetapi Anda tidak boleh bergantung padanya. Untuk MS SQL, satu-satunya hal yang andal mengirimkan baris dalam urutan tertentu, adalah ORDER BY eksplisit klausa.

Tidak hanya RDMBS-es yang berbeda berperilaku berbeda, satu instance tertentu dapat berperilaku berbeda karena pembaruan (tambalan). Tidak hanya itu, bahkan status perangkat lunak RDBMS dapat berdampak:database "hangat" berperilaku berbeda dari database "dingin", tabel kecil berperilaku berbeda dari yang besar.

Bahkan jika Anda memiliki informasi latar belakang tentang implementasi (mis:"ada indeks berkerumun, sehingga kemungkinan data akan dikembalikan berdasarkan urutan indeks berkerumun"), selalu ada kemungkinan bahwa ada mekanisme lain yang tidak Anda lakukan. t tahu tentang itu menyebabkan baris dikembalikan dalam urutan yang berbeda (mis1:"jika sesi lain baru saja melakukan pemindaian tabel penuh dengan ORDER BY eksplisit hasil mungkin telah di-cache; pemindaian penuh berikutnya akan mencoba mengembalikan baris dari cache"; ex2:"a GROUP BY dapat diimplementasikan dengan menyortir data, sehingga memengaruhi urutan baris yang dikembalikan"; ex3:"Jika kolom yang dipilih semuanya ada dalam indeks sekunder yang sudah di-cache di memori, mesin dapat memindai indeks sekunder alih-alih tabel, kemungkinan besar mengembalikan baris berdasarkan urutan indeks sekunder").

Berikut adalah tes yang sangat sederhana yang menggambarkan beberapa poin saya.

Pertama, mulai SQL server (saya menggunakan 2008). Buat tabel ini:

create table test_order (
    id int not null identity(1,1) primary key
,   name varchar(10) not null 
)

Periksa tabel dan saksikan bahwa indeks berkerumun dibuat untuk mendukung primary key pada id kolom. Misalnya, di studio manajemen server sql, Anda dapat menggunakan tampilan hierarki dan menavigasi ke folder indeks di bawah tabel Anda. Di sana Anda akan melihat satu indeks, dengan nama seperti:PK__test_ord__3213E83F03317E3D (Clustered)

Sisipkan baris pertama dengan pernyataan ini:

insert into test_order(name)
select RAND()

Sisipkan lebih banyak baris dengan mengulangi pernyataan ini sebanyak 16 kali:

insert into test_order(name)
select RAND()
from   test_order

Anda sekarang harus memiliki 65536 baris:

select COUNT(*) 
from   test_order

Sekarang, pilih semua baris tanpa menggunakan perintah dengan:

select *
from   test_order

Kemungkinan besar, hasilnya akan dikembalikan berdasarkan urutan kunci utama (walaupun tidak ada jaminan). Berikut hasil yang saya dapatkan (yang memang berdasarkan urutan primary key):

#      id    name
1      1     0.605831
2      2     0.517251
3      3     0.52326
.      .     .......
65536  65536 0.902214

(# bukan kolom tetapi posisi ordinal baris dalam hasil)

Sekarang, buat indeks sekunder pada name kolom:

create index idx_name on test_order(name)

Pilih semua baris, tetapi ambil hanya name kolom:

select name
from   test_order

Kemungkinan besar hasilnya akan dikembalikan berdasarkan urutan indeks sekunder idx_name, karena kueri dapat diselesaikan hanya dengan memindai indeks (i.o.w. idx_name adalah penutup indeks). Inilah hasil yang saya dapatkan, yang memang atas perintah name .

#      name
1      0.0185732
2      0.0185732
.      .........
65536  0.981894

Sekarang, pilih semua kolom dan semua baris lagi:

select * 
from test_order

Inilah hasil yang saya dapatkan:

#      id    name
1      17    0.0185732
2      18    0.0185732
3      19    0.0185732
...    ..    .........

seperti yang Anda lihat, sangat berbeda dari pertama kali kami menjalankan kueri ini. (Sepertinya baris diurutkan oleh indeks sekunder, tetapi saya tidak memiliki penjelasan mengapa harus demikian).

Bagaimanapun, intinya adalah - jangan mengandalkan pesanan implisit. Anda dapat memikirkan penjelasan mengapa urutan tertentu dapat diamati, tetapi meskipun demikian Anda tidak selalu dapat memprediksinya (seperti dalam kasus terakhir) tanpa memiliki pengetahuan mendalam tentang implementasi dan status runtime.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server :Pivot dengan nama kolom khusus

  2. Tambahkan kolom ke tabel dengan nilai default sama dengan nilai kolom yang ada

  3. Bagaimana cara memeriksa hasil pekerjaan paket SSIS setelah menyelesaikan eksekusinya?

  4. Hasil yang dipisahkan koma dalam SQL

  5. SQL Server:tertarik dengan GETDATE()