Tại sao cần thiết?
Khi dữ liệu được lưu trữ trên các thiết bị lưu trữ dựa trên đĩa, nó được lưu trữ dưới dạng các khối dữ liệu. Các khối này được truy cập toàn bộ, làm cho chúng hoạt động truy cập đĩa nguyên tử. Các khối đĩa được cấu trúc theo cách tương tự như các danh sách được liên kết; cả hai đều chứa một phần cho dữ liệu, một con trỏ đến vị trí của nút (hoặc khối) tiếp theo và cả hai không cần phải được lưu trữ liên tục.
Do thực tế là một số bản ghi chỉ có thể được sắp xếp trên một trường, chúng tôi có thể nói rằng tìm kiếm trên một trường không được sắp xếp yêu cầu Tìm kiếm tuyến tính yêu cầu N/2
truy cập khối (trung bình), trong đó N
số lượng khối là cái bàn kéo dài. Nếu trường đó là trường không khóa (nghĩa là không chứa các mục duy nhất) thì toàn bộ không gian bảng phải được tìm kiếm tại N
các truy cập khối.
Trong khi với một trường được sắp xếp, Tìm kiếm nhị phân có thể được sử dụng, có quyền log2 N
truy cập khối. Ngoài ra, vì dữ liệu được sắp xếp theo trường không khóa, phần còn lại của bảng không cần tìm kiếm các giá trị trùng lặp, khi tìm thấy giá trị cao hơn. Do đó, hiệu suất tăng là đáng kể.
Lập chỉ mục là gì?
Lập chỉ mục là một cách sắp xếp một số bản ghi trên nhiều lĩnh vực. Tạo một chỉ mục trên một trường trong bảng sẽ tạo ra một cấu trúc dữ liệu khác chứa giá trị trường và một con trỏ tới bản ghi mà nó liên quan. Cấu trúc chỉ mục này sau đó được sắp xếp, cho phép Tìm kiếm nhị phân được thực hiện trên nó.
Nhược điểm của việc lập chỉ mục là các chỉ mục này yêu cầu không gian bổ sung trên đĩa do các chỉ mục được lưu trữ cùng nhau trong một bảng bằng công cụ MyISAM, tệp này có thể nhanh chóng đạt đến giới hạn kích thước của hệ thống tệp bên dưới nếu nhiều trường trong cùng một bảng được lập chỉ mục .
Làm thế nào nó hoạt động?
Đầu tiên, hãy phác thảo một lược đồ bảng cơ sở dữ liệu mẫu;
Tên trường Kiểu dữ liệu Kích thước trên đĩa
id (Khóa chính) INT 4 byte không dấu
FirstName Char (50) 50 byte
LastName Char (50) 50 byte
emailAddress Char (100) 100 byte
Lưu ý : char đã được sử dụng thay cho varchar để cho phép kích thước chính xác trên giá trị đĩa. Cơ sở dữ liệu mẫu này chứa năm triệu hàng và không được lập trình. Hiệu suất của một số truy vấn bây giờ sẽ được phân tích. Đây là một truy vấn sử dụng id (trường khóa được sắp xếp) và một truy vấn sử dụng FirstName (trường không được sắp xếp không khóa).
Ví dụ 1 - sắp xếp so với các trường chưa sắp xếp
Dựa vào cơ sở dữ liệu mẫu của chúng tôi về các r = 5,000,000
bản ghi có kích thước cố định cho độ dài bản ghi R = 204
byte và chúng được lưu trữ trong một bảng bằng cách sử dụng công cụ MyISAM đang sử dụng các B = 1,024
byte kích thước khối mặc định . Hệ số chặn của bảng sẽ là bfr = (B/R) = 1024/204 = 5
các bản ghi trên mỗi khối đĩa. Tổng số khối cần thiết để giữ bảng là N = (r/bfr) = 5000000/5 = 1,000,000
các khối.
Một tìm kiếm tuyến tính trên trường id sẽ yêu cầu trung bình các N/2 = 500,000
truy cập khối để tìm giá trị, với điều kiện trường id là trường khóa. Nhưng vì trường id cũng được sắp xếp, nên việc tìm kiếm nhị phân có thể được tiến hành yêu cầu trung bình số log2 1000000 = 19.93 = 20
lượt truy cập khối. Ngay lập tức chúng ta có thể thấy đây là một sự cải thiện mạnh mẽ.
Bây giờ trường FirstName không được sắp xếp cũng không phải là trường khóa, vì vậy không thể tìm kiếm nhị phân, cũng không phải là các giá trị duy nhất và do đó bảng sẽ yêu cầu tìm kiếm đến cuối để N = 1,000,000
truy cập khối chính xác . Đây là tình huống mà chỉ mục nhằm mục đích để sửa chữa.
Cho rằng một bản ghi chỉ mục chỉ chứa trường được lập chỉ mục và một con trỏ tới bản ghi gốc, lý do là nó sẽ nhỏ hơn bản ghi đa trường mà nó trỏ tới. Vì vậy, bản thân chỉ mục yêu cầu ít khối đĩa hơn bảng gốc, do đó yêu cầu ít truy cập khối hơn để lặp qua. Lược đồ cho một chỉ mục trên trường FirstName được nêu dưới đây;
Tên trường Kiểu dữ liệu Kích thước trên đĩa
FirstName Char (50) 50 byte
(con trỏ bản ghi) 4 byte đặc biệt
Lưu ý : Con trỏ trong MySQL có độ dài 2, 3, 4 hoặc 5 byte tùy thuộc vào kích thước của bảng.
Ví dụ 2 - lập chỉ mục
Đưa ra cơ sở dữ liệu mẫu các r = 5,000,000
bản ghi của chúng tôi với độ dài bản ghi chỉ số của R = 54
byte và sử dụng B = 1,024
byte kích thước khối mặc định . Hệ số chặn của chỉ mục sẽ là bfr = (B/R) = 1024/54 = 18
các bản ghi trên mỗi khối đĩa. Tổng số khối cần thiết để giữ chỉ mục là N = (r/bfr) = 5000000/18 = 277,778
các khối.
Bây giờ một tìm kiếm sử dụng trường FirstName có thể sử dụng chỉ mục để tăng hiệu suất. Điều này cho phép tìm kiếm nhị phân của chỉ mục với số lần log2 277778 = 18.08 = 19
truy cập khối trung bình . Để tìm địa chỉ của bản ghi thực tế, yêu cầu quyền truy cập khối tiếp theo để đọc, đưa tổng số 19 + 1 = 20
truy cập chặn, khác xa so với truy cập khối 1.000.000 được yêu cầu để tìm kết quả trùng khớp FirstName trong bảng không được lập chỉ mục.
Nó nên được sử dụng lúc nào?
Do việc tạo một chỉ mục yêu cầu không gian đĩa bổ sung (277.778 khối bổ sung từ ví dụ trên, tăng ~ 28%) và quá nhiều chỉ số có thể gây ra sự cố phát sinh từ giới hạn kích thước hệ thống tệp, phải sử dụng cẩn thận để chọn đúng các trường để lập chỉ mục.
Vì các chỉ mục chỉ được sử dụng để tăng tốc độ tìm kiếm trường phù hợp trong các bản ghi, nên lý do là các trường lập chỉ mục được sử dụng cho đầu ra sẽ chỉ đơn giản là lãng phí không gian đĩa và thời gian xử lý khi thực hiện thao tác chèn hoặc xóa, và do đó nên tránh. Cũng với bản chất của tìm kiếm nhị phân, tính chính xác hoặc tính duy nhất của dữ liệu là quan trọng. Lập chỉ mục trên một lĩnh vực có số lượng thẻ là 2 sẽ chia dữ liệu thành một nửa, trong khi đó số lượng thẻ là 1.000 sẽ trả về khoảng 1.000 bản ghi. Với số lượng cardin thấp như vậy, hiệu quả sẽ giảm xuống thành một loại tuyến tính và trình tối ưu hóa truy vấn sẽ tránh sử dụng chỉ mục nếu cardinality nhỏ hơn 30% số lượng bản ghi, làm cho chỉ mục trở nên lãng phí không gian.