Bagaimana cara SQL Server menghasilkan ketika bergabung digunakan?

10

Bagaimana SQL Server mengetahui urutan catatan di set hasil eksekusi kueri?

Saya mencoba membuat kepala atau ekor tetapi menemukan diri saya menggaruk-garuk kepala. Ketika saya mengubah bidang saya memilih urutan juga berubah. Ketika saya menjalankan SQL di bawah ini dengan SELECT *saya mendapatkan catatan yang sama tetapi dalam urutan yang jauh berbeda.

 SELECT TOP (900)
    AD.ATTACHMENTID,
    AD.NAME,
    AD.ISINLINE,
    AD.INSERTEDDATETIME,
    ATMT.ATTACHMENTBLOB,
    U.UFID
  FROM ATTACHMENTDETAIL AD WITH (NOLOCK)
  INNER JOIN MESSAGEATTACHMENT MA ON MA.ATTACHMENTID = AD.ATTACHMENTID
  INNER JOIN ATTACHMENT ATMT ON ATMT.ATTACHMENTID = AD.ATTACHMENTID
  INNER JOIN MESSAGE MSG ON MSG.ID = MA.MESSAGEID
  INNER JOIN MESSAGEDETAIL MD ON MD.MESSAGEID = MA.MESSAGEID
  INNER JOIN [USER] U ON U.ID = MD.USERID
  LEFT OUTER JOIN XmlExtractionMapping XM ON MA.MESSAGEID = XM.MessageId
    WHERE AD.FILEBOXTOKEN IS NULL 
    AND (XM.XMLEXTRACTIONDATE IS NOT NULL OR 
         (MSG.MESSAGESOURCEID = 1 AND MD.FolderId <> -4))
    AND AD.ISINLINE = 'FALSE'
kacalapy
sumber
6
Beberapa komentar / pertanyaan: (1) mengapa menggunakan tombol turbo pixie-dust ajaib NOLOCK hanya pada satu meja? Sudahkah Anda mempertimbangkan untuk menggunakan RCSI alih-alih voodoo? (2) mengapa Anda tidak menggunakan awalan skema yang tepat? Untuk yang pertama, cari di web NOLOCK- Anda akan melihat segala macam alasan mengapa Anda tidak boleh menggunakannya. Untuk yang terakhir, lihat sqlblog.com/blogs/aaron_bertrand/archive/2009/10/11/...
Aaron Bertrand
RCSI? tolong jelaskan ...
kacalapy
2
RCSI = Baca Pengambilan Snapshot yang Dilakukan. Lihat stackoverflow.com/questions/816650/...
Aaron Bertrand
Tanpa ORDER BYklausa, SQL Server (dan RDBMS lainnya) melakukan apa pun rasanya .
Nick Chammas

Jawaban:

17

Karena Anda belum memberi tahu SQL Server cara memesan hasil, itu bebas untuk melakukannya dalam apa pun yang paling efisien. Dengan cara ini akan tergantung pada apa yang termurah untuk disortir, dan kolom yang Anda pilih akan mengarahkannya karena pada gilirannya tergantung pada indeks termurah yang digunakan untuk mendapatkan informasi yang diminta oleh kueri. Ini dapat berubah dari eksekusi ke eksekusi tidak hanya dengan mengubah teks kueri tetapi juga oleh hal-hal seperti perubahan data, pembaruan statistik, freeproccache, paket layanan, perbaikan terbaru, dll. Ini sangat mudah berubah dengan begitu banyak tabel yang terlibat jika data yang mendasarinya berubah dengan cepat , seperti yang cenderung dilakukan dalam aplikasi OLTP.

Jika Anda ingin pesanan yang dapat diprediksi, mengapa Anda tidak menggunakan ORDER BYpermintaan itu? Seperti ditulis, menspesifikasikan SQL yang setiap 900 baris dapat diterima, dalam urutan apapun.

Meskipun, dalam banyak kasus, Anda melihat urutan yang sama berulang kali untuk permintaan yang sama, tidak ada jaminan kecuali jika Anda mengatakannya ORDER BY <something>.

Aaron Bertrand
sumber