Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Máy chủ sql sắp xếp dữ liệu của bạn như thế nào?

Mặc dù thật tốt khi tự hỏi về cách giải thích rằng bạn thường thấy cùng một thứ tự, nhưng tôi muốn chỉ ra rằng không bao giờ là một ý tưởng hay nếu dựa vào thứ tự ngầm gây ra bởi việc triển khai cụ thể của cơ sở dữ liệu bên dưới. Nói cách khác, thật tuyệt khi biết tại sao, nhưng bạn đừng bao giờ dựa vào nó. Đối với MS SQL, thứ duy nhất phân phối các hàng theo một thứ tự nhất định một cách đáng tin cậy, là ORDER BY rõ ràng mệnh đề.

Không chỉ các RDMBS khác nhau hoạt động khác nhau, một phiên bản cụ thể có thể hoạt động khác nhau do một bản cập nhật (bản vá). Không chỉ vậy, ngay cả trạng thái của phần mềm RDBMS cũng có thể có tác động:cơ sở dữ liệu "ấm" hoạt động khác với cơ sở dữ liệu "lạnh", một bảng nhỏ hoạt động khác với một bảng lớn.

Ngay cả khi bạn có thông tin cơ bản về việc triển khai (ví dụ:"có một chỉ mục được phân nhóm, do đó có khả năng dữ liệu sẽ được trả về theo thứ tự của chỉ mục được phân nhóm"), luôn có khả năng có một cơ chế khác mà bạn không làm ' Tôi không biết về điều đó khiến các hàng được trả về theo một thứ tự khác (ví dụ:"nếu một phiên khác vừa quét toàn bộ bảng với một ORDER BY rõ ràng tập kết quả có thể đã được lưu vào bộ nhớ đệm; quá trình quét toàn bộ tiếp theo sẽ cố gắng trả lại các hàng từ bộ nhớ cache "; ex2:" a GROUP BY có thể được triển khai bằng cách sắp xếp dữ liệu, do đó tác động đến thứ tự các hàng được trả về "; ví dụ:" Nếu tất cả các cột đã chọn đều nằm trong chỉ mục phụ đã được lưu trong bộ nhớ, công cụ có thể quét chỉ mục phụ thay vì bảng, rất có thể trả về các hàng theo thứ tự của chỉ mục phụ ").

Đây là một bài kiểm tra rất đơn giản minh họa một số điểm của tôi.

Đầu tiên, khởi động máy chủ SQL (tôi đang sử dụng năm 2008). Tạo bảng này:

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

Kiểm tra bảng và chứng kiến ​​rằng một chỉ mục gộp đã được tạo để hỗ trợ primary key trên id cột. Ví dụ:trong studio quản lý máy chủ sql, bạn có thể sử dụng chế độ xem dạng cây và điều hướng đến thư mục chỉ mục bên dưới bảng của mình. Ở đó, bạn sẽ thấy một chỉ mục, có tên như:PK__test_ord__3213E83F03317E3D (Clustered)

Chèn hàng đầu tiên với câu lệnh này:

insert into test_order(name)
select RAND()

Chèn thêm hàng bằng cách lặp lại câu lệnh này 16 lần:

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

Bây giờ bạn sẽ có 65536 hàng:

select COUNT(*) 
from   test_order

Bây giờ, hãy chọn tất cả các hàng mà không cần sử dụng thứ tự bằng cách:

select * 
from test_order

Nhiều khả năng, kết quả sẽ được trả về theo thứ tự của khóa chính (mặc dù không có gì đảm bảo). Đây là kết quả tôi nhận được (thực sự là theo thứ tự của khóa chính):

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

(# không phải là một cột mà là vị trí thứ tự của hàng trong kết quả)

Bây giờ, hãy tạo một chỉ mục phụ trên name cột:

create index idx_name on test_order(name)

Chọn tất cả các hàng, nhưng chỉ truy xuất name cột:

select name
from   test_order

Nhiều khả năng kết quả sẽ được trả về theo thứ tự của chỉ mục phụ idx_name, vì truy vấn có thể được giải quyết bằng cách chỉ quét chỉ mục (i.o.w. idx_name là một phủ mục lục). Đây là kết quả tôi nhận được, thực sự là theo thứ tự của name .

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

Bây giờ, hãy chọn lại tất cả các cột và tất cả các hàng:

select * 
from test_order

Đây là kết quả tôi nhận được:

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

như bạn có thể thấy, hoàn toàn khác với lần đầu tiên chúng tôi chạy truy vấn này. (Có vẻ như các hàng được sắp xếp theo chỉ mục phụ, nhưng tôi không có lời giải thích tại sao lại như vậy).

Dù sao, điểm mấu chốt là - đừng dựa vào trật tự ngầm định. Bạn có thể nghĩ ra lời giải thích tại sao một thứ tự cụ thể có thể được quan sát, nhưng ngay cả khi đó bạn không thể luôn dự đoán nó (như trong trường hợp sau) mà không có kiến ​​thức sâu sắc về việc triển khai và trạng thái thời gian chạy.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để tắt các Ràng buộc cho tất cả các bảng và kích hoạt nó?

  2. Các cải tiến của Service Broker trong SQL Server 2016

  3. Cú pháp cho một truy vấn tham số trong Python (pyodbc)

  4. JBoss kết nối lại khi hết thời gian kết nối

  5. Không thể thả đối tượng vì nó được tham chiếu bởi ràng buộc NGOẠI KHÓA - Hướng dẫn SQL Server / TSQL Phần 74