Chỉ số của Nhật Bản có nghĩa là gì trên RDBMS? [đóng cửa]


21

Tôi sử dụng các chỉ mục như hầu hết các nhà phát triển thực hiện (chủ yếu là trên ... tốt! Chỉ mục), nhưng tôi chắc chắn có rất nhiều cách tinh tế để tối ưu hóa cơ sở dữ liệu bằng cách sử dụng chỉ mục. Tôi không chắc liệu nó có đặc trưng cho bất kỳ triển khai DBMS nào không.

Câu hỏi của tôi là: các ví dụ hay về cách sử dụng chỉ mục (trừ các trường hợp cơ bản, rõ ràng) và DBMS tối ưu hóa cơ sở dữ liệu của nó như thế nào khi bạn chỉ định một chỉ mục trên bảng?


Trong suy nghĩ thêm về câu hỏi này, câu hỏi này quá chung chung cho trang web này. Nếu chúng tôi thay đổi phạm vi câu hỏi có thể phù hợp, nếu không thì câu hỏi này không phù hợp với trang web.
jcolebrand

Tôi muốn giải thích các chỉ mục bằng cách sử dụng phép ẩn dụ thư viện mysqlperformanceblog.com/2011/08/30/ Khăn Xem nếu điều đó có ích ..
Jonathan

Câu trả lời:


11

Hãy nghĩ về một chỉ mục là "mục lục" ... đó là một danh sách được sắp xếp các con trỏ tới các vị trí trong một tệp, còn gọi là offset. Giả sử rằng bạn có hàng triệu bản ghi được lưu trữ trong một bảng, thay vì tìm kiếm bảng cho các tiêu chí khớp, sẽ nhanh hơn nhiều khi tham chiếu danh sách được sắp xếp cho các kết quả khớp, sau đó xếp các con trỏ vào các hàng khớp cụ thể. Một ví dụ hoàn hảo về chỉ mục là trường khóa chính của bảng, điển hình nhất là trường "id" của nó. Nếu bạn muốn id hàng # 11234566, yêu cầu chỉ mục cho con trỏ tới dữ liệu nhanh hơn nhiều so với quét nguồn dữ liệu cho vị trí 11234566.

Đây là một cách sử dụng lập chỉ mục không quá rõ ràng:

CREATE TABLE activity_log (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
activity_type_id SMALLINT UNSIGNED NOT NULL,
datetime_created DATETIME
KEY(activity_type_id),
PRIMARY KEY(id)
);
CREATE TABLE activity_log_to_date_key (
activity_log_id INT UNSIGNED NOT NULL,
date_created_key  INT UNSIGNED NOT NULL REFERENCES dim_datetime(id),
UNIQUE KEY(activity_log_id),
KEY(date_created_key)
);
CREATE TABLE dim_datetime (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
date_hour DATETIME NOT NULL,
PRIMARY KEY(id),
KEY(date_hour)
);

Hoạt động của bạn có thể tạo bản ghi nhật ký của bạn, nhưng sau đó tạo một tham chiếu đến một datetime được lập chỉ mục nhanh hơn để tìm kiếm / sắp xếp so với bảng nhật ký của bạn. Sau đó tham gia lại bảng nhật ký của bạn trên khóa chính của nó. Nếu bạn cần tôi mở rộng về điều này, hãy cho tôi biết. Tôi hy vọng điều này có ý nghĩa.

Truy vấn mẫu:

SELECT a.activity_log_id, al.activity_type_id, al.datetime_created
FROM activity_log_to_date_key a 
INNER JOIN dim_datetime d ON (d.id = a.date_created_key)
LEFT JOIN activity_log al ON (al.id = a.activity_log_id)
WHERE d.date_hour BETWEEN '2009-01-01 00:00:00' AND '2009-06-01 12:00:00';

cảm ơn, điều đó rất rõ ràng Trong ví dụ của bạn, "PRIMary" sẽ thay đổi cách RDMBS lưu trữ "offset" hay nó chỉ được sử dụng cho các ràng buộc duy nhất?
Thomas Joulin

9

Một điểm mà nhiều người dường như bỏ lỡ là DBMS thường sẽ (hoặc chỉ có thể) chỉ sử dụng một chỉ mục cho mỗi tham chiếu bảng trong một truy vấn và nếu nó có thể và sử dụng nhiều chỉ mục thì có thể sử dụng kết hợp nhiều hơn chỉ số nếu có.

Chẳng hạn, nếu tìm kiếm một bảng lớn cho các hàng WHERE AnIntegerColumn = 42 AND AnOtherInt = 69, tuyến đường nhanh nhất đến các hàng đó sẽ là một chỉ mục trên hai cột AnIntegerColumn và AnOtherInt. Nếu bạn chỉ có một chỉ mục cho từng cá nhân nhưng không có chỉ mục kết hợp, DB sẽ tìm kiếm một hoặc chỉ mục khác và lọc riêng kết quả với mệnh đề thứ hai hoặc quét cả hai và kết quả sau đó.

Một thao tác đơn giản phổ biến khác có thể được cải thiện với các chỉ mục tổng hợp là WHERE SomeColumn = <SomeValue> ORDER BY SomeOtherColumn- nếu có một chỉ mục trên someColumn và someOtherColumn (theo đúng thứ tự), các hoạt động lọc và đặt hàng có thể được thực hiện cùng một lúc trong một số trường hợp.

Tất nhiên, việc thêm quá nhiều chỉ mục có thể là một sự tối ưu hóa tồi, vì không gian thêm được sử dụng để lưu trữ các chỉ mục (và tải IO để duy trì chúng nếu DB của bạn thấy nhiều thao tác ghi) có thể là một vấn đề tồi tệ hơn so với các truy vấn đọc tối ưu hơn một chút Vì vậy, đừng làm quá.


2

David và Randy có điều này được bảo hiểm. Tôi chỉ muốn nói thêm rằng các EXPLAINlệnh có thể là một trợ giúp rất lớn trong việc tìm ra khi bạn sẽ nhận được một lớn tiết kiệm trong việc tạo ra một chỉ số, cũng như gợi ý mà chỉ là cần thiết. Nó sẽ hiển thị các bước mà cơ sở dữ liệu đang thực hiện để chạy truy vấn của bạn, vì vậy bạn biết bit nào đang mất nhiều thời gian nhất.


Để thêm vào câu trả lời của Gaurav, hãy sử dụng "EXPLAIN EXTENDED", sau đó nhập ngay "SHOW WARNING" để xem cách truy vấn của bạn được dịch.
Randomx

1

Một điều tôi chưa từng thấy được đề cập ở đây là khi bạn có nhiều hơn một đĩa, bạn có thể muốn đặt chỉ mục của mình vào một đĩa khác với nơi dữ liệu thực sự ở đó. Điều này có thể tăng tốc một số hoạt động lên. Tôi nghĩ rằng điều này xứng đáng một câu hỏi trong chính nó tho.


Điều đó đã từng đúng nhưng ngày nay chúng tôi nói đừng cố gắng đoán thứ hai hệ thống con I / O của bạn. Bạn không biết nơi nào một mảng lưu trữ sẽ đặt dữ liệu của bạn.
Gaius

1
@gaius Tôi có nghĩa là nếu bạn không có thiết lập RAID5 (hoặc tương tự), để đặt các chỉ mục trên E:, dữ liệu trên F:, v.v.
jcolebrand
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.