Tiếng Việt

Công cụ dành cho nhà phát triển · Trình tạo UUID

Ngẫu nhiên UUID Khóa chính và phân mảnh cây B: Điều gì thực sự xảy ra

· Tại sao nó quan trọng

uuid mật mã browser-apis

Sơ đồ cây B hiển thị các phần chèn tuần tự lấp đầy một trang so với các phần chèn ngẫu nhiên nằm rải rác trên nhiều trang
Hình minh họa vector ToolAcre gốc

Các khóa v4 ngẫu nhiên chèn vào các trang chỉ mục ngẫu nhiên và các chỉ mục được nhóm trả tiền cho việc đó. Bài đăng này giải thích cơ chế, chi phí lưu trữ văn bản so với nhị phân và nơi các UUID theo thứ tự thời gian thay đổi hình ảnh.

Quá trình chèn chậm lại khi bảng phát triển - triệu chứng gửi các DBA đang xem xét lựa chọn khóa của họ

Việc chèn một hàng có UUID ngẫu nhiên làm khóa chính trong cơ sở dữ liệu có chỉ mục được nhóm sẽ khiến cơ sở dữ liệu chèn hàng mới vào một vị trí ngẫu nhiên trong cấu trúc cây B. Các khóa tuần tự sẽ được thêm vào trang lá ngoài cùng bên phải, giữ tất cả các phần chèn trong một vùng lưu trữ bộ đệm nhỏ. Các khóa ngẫu nhiên phân tán các phần chèn trên toàn bộ chỉ mục, buộc cơ sở dữ liệu phải duyệt qua và sửa đổi các trang cách xa nhau trong bộ nhớ vật lý. Khi bảng phát triển và cây sâu hơn, mỗi lần chèn sẽ chạm vào nhiều trang hơn và gây ra nhiều thao tác I/O hơn. Hoạt động tưởng chừng rẻ ở một nghìn hàng lại trở nên đắt đỏ ở mức một triệu. Đây không phải là một vấn đề lý thuyết; nó biểu hiện dưới dạng sự suy giảm có thể đo lường được trong thông lượng chèn.

Cách lấp đầy cây B theo cụm - các khóa tuần tự sẽ được thêm vào trang cuối cùng; các phím ngẫu nhiên chạm vào các trang trên toàn bộ chỉ mục

Cơ chế này là nền tảng cho cách thức hoạt động của cây B vì chúng duy trì thứ tự khóa được sắp xếp trong các trang lá. Khi bạn chèn một hàng có khóa 10,001 vào bảng đã lưu trữ khóa 1 đến 10,000, cơ sở dữ liệu sẽ biết hàng đó thuộc về vị trí nào: ở cuối, ở trang ngoài cùng bên phải hiện có nếu có khoảng trống hoặc trong một trang mới được thêm vào bên phải. Khi bạn chèn một hàng có UUID ngẫu nhiên như 7524fae2-7dec-11d0-a765-00a0c91e6bf6 vào cùng một bảng, cơ sở dữ liệu phải điều hướng cây để tìm trang lá chứa các khóa trong phạm vi UUID đó, xác định vị trí chính xác trong trang đó và chèn hàng. Nếu trang đó đầy, nó sẽ tách ra, chuyển một nửa nội dung của nó sang một trang mới và cập nhật nút cha.

Phân tách trang và áp lực bộ nhớ đệm — tại sao việc chèn ngẫu nhiên tốn nhiều I/O hơn và tại sao hiệu ứng lại tăng theo kích thước bảng

Khóa ngẫu nhiên tạo ra kiểu chèn trong trường hợp xấu nhất vì mỗi lần chèn sẽ rơi vào một vị trí ngẫu nhiên trong cây thay vì gắn vào trang ngoài cùng bên phải. Cơ sở dữ liệu phải tìm kiếm đúng trang, việc này thường tốn nhiều lần đọc trang—mỗi cấp độ của cây. Sau đó, nó phải sửa đổi trang đó, điều này có thể kích hoạt sự phân chia lan truyền lên cây. Nhiều trang được sửa đổi hơn, nhiều thao tác ghi diễn ra hơn và vùng đệm bộ nhớ sẽ lấp đầy các trang từ các vùng khác nhau của cây thay vì tập trung vào điểm chèn đang hoạt động. Tỷ lệ thiếu bộ nhớ đệm tăng lên và I/O trở thành nút cổ chai, với tốc độ chèn không thay đổi khi bảng phát triển lên quy mô lớn hơn.

Văn bản hoặc nhị phân — chuỗi 36 ký tự so với cột 16 byte gốc uuid hoặc nhị phân(16) và ảnh hưởng đến kích thước chỉ mục

Chi phí không đồng đều giữa các công cụ cơ sở dữ liệu vì các hệ thống khác nhau tối ưu hóa việc quản lý trang theo cách khác nhau. Cơ sở dữ liệu được nén mạnh, kích thước trang nhỏ hoặc hoạt động trong bộ nhớ có thể hiển thị sự khác biệt nhỏ hơn về hiệu suất giữa các khóa tuần tự và khóa ngẫu nhiên. Cơ sở dữ liệu với các trang lớn, đĩa cơ hoặc giới hạn bộ nhớ nghiêm ngặt sẽ có biểu hiện xuống cấp nghiêm trọng. Vấn đề có thể quan sát và đo lường được: đo lường tỷ lệ chèn ở 1,000 hàng, 100,000 hàng và 1,000,000 hàng. Nếu tốc độ trên giây giảm mạnh ở quy mô lớn hơn, thì bạn đang gặp phải hình phạt chèn ngẫu nhiên với cấu hình cơ sở dữ liệu và phần cứng cụ thể của mình.

Các lựa chọn thay thế theo thứ tự thời gian - cách UUIDv7 và ULID giữ tính duy nhất trong khi chèn vào cuối chỉ mục

UUID dưới dạng chuỗi sử dụng 36 ký tự ở dạng văn bản hoặc 16 bytes dưới dạng loại nhị phân UUID tùy thuộc vào định dạng lưu trữ được chọn. Chuỗi gồm 36 ký tự trong cột UTF-8 hoặc ASCII là 36 bytes, so với 8 bytes cho số nguyên 64-bit. Chỉ mục trên cột chuỗi-UUID lớn hơn ba lần so với chỉ mục trên cột số nguyên, giả sử không áp dụng kỹ thuật nén. Chỉ mục lớn hơn có nghĩa là có ít trang chỉ mục phù hợp với vùng đệm hơn, nghĩa là sẽ có ít lần truy cập bộ đệm hơn khi duyệt qua cây. Chỉ mục nhỏ hơn phù hợp với RAM hoạt động tốt hơn chỉ mục lớn phải được đọc từ đĩa trên mọi truy vấn, bất kể thứ tự chèn hay mẫu khối lượng công việc.

Ví dụ đã hoạt động - cùng một khối lượng công việc chèn được mô tả cho bảng khóa ngẫu nhiên và bảng khóa theo thứ tự thời gian, về mặt chất lượng, không có điểm chuẩn được phát minh

Sự khác biệt về bộ nhớ có ý nghĩa quan trọng đối với cả chỉ mục chính và chỉ mục phụ vì mọi chỉ mục phụ bao gồm khóa chính phải lưu trữ toàn bộ giá trị 36 ký tự UUID hoặc 16 byte nhị phân UUID. Điều này làm cho các chỉ mục phụ lớn hơn đáng kể so với các chỉ mục sử dụng khóa số nguyên để tra cứu khóa chính. Bản sao, bản sao lưu và tập kết quả truy vấn đều tăng trưởng tương ứng với kích thước chỉ mục lớn hơn. Trình tạo ToolAcre UUID tạo ra các giá trị tương thích nhị phân; việc lưu trữ chúng dưới dạng nhị phân(16) hoặc GUID tùy thuộc vào cơ sở dữ liệu sẽ tiết kiệm dung lượng so với varchar(36) và cải thiện hiệu quả bộ nhớ đệm trên toàn bộ bảng. Việc tối ưu hóa lưu trữ này rất quan trọng đối với các hệ thống quy mô lớn.

Điều này không bao gồm những gì - các bảng và cơ sở dữ liệu được tổ chức theo đống trong đó khóa chính không được nhóm lại, trong đó hiệu ứng nhỏ hơn

Một cách tối ưu hóa phổ biến là lưu trữ UUID dưới dạng nhị phân nội bộ và chỉ hiển thị nó dưới dạng chuỗi khi cần cho API hoặc giao diện người dùng. Các hoạt động chỉ mục và nối hoạt động ở dạng nhị phân nhỏ gọn; phản hồi API hoặc mã ứng dụng chuyển đổi thành biểu diễn chuỗi. Một số cơ sở dữ liệu cung cấp các loại GUID hoặc UUID tích hợp sẵn để tự động xử lý chuyển đổi này. Những người khác yêu cầu hoạt động truyền rõ ràng. Sự khác biệt về hiệu suất giữa các cột 36byte và 16-byte là có thật: một bảng có một triệu hàng và khóa cột 36 byte so với 16 byte UUID khác nhau 20 MB cho mỗi cấp chỉ mục. Đây có thể là sự khác biệt giữa chỉ mục phù hợp với bộ nhớ đệm L3 và yêu cầu tìm nạp bộ nhớ.

Bài học rút ra: biết chỉ mục của bạn trước khi chọn phiên bản - trình tạo ToolAcre tạo ra các UUID ngẫu nhiên; sử dụng bài đăng để quyết định xem nó có phù hợp với công cụ lưu trữ của bạn không

Sự cân bằng giữa hiệu suất chèn, kích thước chỉ mục và đặc điểm truy vấn đòi hỏi các quyết định kiến ​​trúc dựa trên mẫu khối lượng công việc. Khóa chuỗi tuần tự có thể được chèn nhanh nếu các chuỗi tăng dần, chẳng hạn như các chuỗi dựa trên dấu thời gian, nhưng sẽ tiêu tốn cùng một không gian với các UUID ngẫu nhiên và rò rỉ thông tin tạm thời. UUID ngẫu nhiên rõ ràng hơn về mặt ngữ nghĩa và không có thành phần dấu thời gian nào bị rò rỉ nhưng chậm hơn khi chèn vào chỉ mục được nhóm và có dung lượng lưu trữ tổng thể lớn hơn. Các lựa chọn thay thế theo thứ tự thời gian như UUIDv7 kết hợp các lợi ích bằng cách duy trì vị trí chèn trong khi tránh rò rỉ dấu thời gian trong số nhận dạng ngẫu nhiên của phiên bản 4.