2009-12-08 39 views
8

Nếu tôi có một bảngchỉ mục có nhiều cột - ok khi thực hiện truy vấn trên chỉ một cột?

create table sv (id integer, data text) 

và một chỉ số:

create index myindex_idx on sv (id,text) 

sẽ này vẫn có ích nếu tôi đã làm một truy vấn

select * from sv where id = 10 

lý do tôi cho hỏi là i' m xem xét một tập hợp các bảng có bất kỳ chỉ mục nào và xem các kết hợp khác nhau của các truy vấn chọn lọc. Một số chỉ sử dụng một cột khác có nhiều hơn một cột. Tôi có cần phải có chỉ mục cho cả hai bộ hoặc là một chỉ số bao gồm tất cả ok không? Tôi đang thêm các chỉ mục để tra cứu nhanh hơn so với quét toàn bộ bảng.

Ví dụ (dựa trên câu trả lời của Matt Huggins):

select * from table where col1 = 10 
select * from table where col1 = 10 and col2=12 
select * from table where col1 = 10 and col2=12 and col3 = 16 

tất cả có thể được bao phủ bởi bảng chỉ mục (co1l1, col2, col3) nhưng

select * from table where col2=12 

sẽ cần chỉ số khác?

+0

Tôi chỉ <3 StackOverflow. Câu trả lời tuyệt vời cách tốt hơn so với dự kiến. Tôi chấp nhận câu trả lời mà tôi đã sử dụng và cho phép câu trả lời được bầu chọn cao nhất ngay bên dưới câu trả lời được chấp nhận – svrist

Trả lời

15

Nó sẽ hữu ích vì chỉ mục trên (id, văn bản) chỉ mục đầu tiên theo id, rồi văn bản tương ứng.

  • Nếu bạn truy vấn theo id, chỉ mục này sẽ được sử dụng.
  • Nếu bạn truy vấn theo id & văn bản, chỉ mục này sẽ được sử dụng.
  • Nếu bạn truy vấn bằng văn bản, chỉ mục này sẽ KHÔNG được sử dụng.

Chỉnh sửa: khi tôi nói "hữu ích", ý tôi là hữu ích về tốc độ/tối ưu hóa truy vấn. Như Sune Rievers đã chỉ ra, nó sẽ không có nghĩa là bạn sẽ nhận được một bản ghi duy nhất được cung cấp chỉ ID (trừ khi bạn chỉ định ID là duy nhất trong định nghĩa bảng của bạn).

+2

Cũng có thể sử dụng nó nếu bạn truy vấn bằng 'văn bản' - ước tính chi phí có thể vẫn ưu tiên quét chỉ mục, quét chỉ mục hoặc quét chỉ mục đầy đủ nhanh. –

2

Tôi giả sử id là khóa chính. Không có điểm trong việc thêm khóa chính vào chỉ mục, vì điều này sẽ luôn là duy nhất. Thêm một cái gì đó độc đáo cho một cái gì đó khác cũng sẽ là duy nhất.

Thêm chỉ mục duy nhất vào text, nếu bạn thực sự cần nó, nếu không chỉ sử dụng id là tính duy nhất cho bảng.

Nếu id không phải là khóa chính của bạn, khi đó bạn sẽ không được đảm bảo nhận được kết quả duy nhất từ ​​truy vấn của mình.

Về ví dụ cuối cùng của bạn với tra cứu trên col2, tôi nghĩ bạn có thể cần một chỉ mục khác. Tuy nhiên, các chỉ mục không phải là giải pháp xử lý tất cả các vấn đề hiệu suất, đôi khi thiết kế cơ sở dữ liệu của bạn hoặc các truy vấn của bạn cần được tối ưu hóa, ví dụ như được viết lại vào các thủ tục lưu sẵn (trong khi tôi không hoàn toàn chắc chắn rằng Oracle có chúng). tương đương).

+1

Việc thêm một cột khác vào chỉ mục PK có thể có giá trị nếu nó cho phép một số lượng truy vấn đáng kể chỉ sử dụng chỉ mục và tránh truy cập bảng hoàn toàn. –

+0

Đúng, nhưng đó cũng là trường hợp khi thêm chỉ mục vào cột khác (khóa chính). Có thể có mức tăng hiệu suất nhỏ trong khóa phức hợp trên khóa giá trị duy nhất + một chỉ mục khác. –

8

Oracle hỗ trợ một số cách sử dụng một chỉ mục, và bạn nên bắt đầu bằng cách tìm hiểu tất cả trong số họ để có thể đọc nhanh ở đây: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#sthref973

truy vấn của bạn select * from table where col2=12 hữu ích có thể tận dụng một chỉ số skip quét nếu hàng đầu cột có số lượng thẻ rất thấp, hoặc quét nhanh chỉ mục đầy đủ nếu không. Đây có lẽ sẽ là tốt cho chạy báo cáo, tuy nhiên đối với một truy vấn OLTP nó có khả năng là bạn sẽ làm tốt hơn để tạo ra một chỉ mục với col2 là cột hàng đầu.

+1

+1 Để đề cập đến việc quét chỉ mục. Nén chỉ mục, dữ liệu cardinality, thống kê, tất cả cùng chơi để xác định kế hoạch sử dụng. – ewernli

2

Nếu trình điều khiển phía sau câu hỏi của bạn là bạn có bảng có nhiều cột và bất kỳ kết hợp nào của các cột này có thể được sử dụng trong truy vấn, thì bạn nên xem chỉ mục BITMAP.

Nhìn vào ví dụ của bạn:

select * from mytable where col1 = 10 and col2=12 and col3 = 16 

Bạn có thể tạo ra 3 chỉ số bitmap:

create bitmap index ix_mytable_col1 on mytable(col1); 
create bitmap index ix_mytable_col2 on mytable(col2); 
create bitmap index ix_mytable_col3 on mytable(col3); 

Những chỉ số bitmap có lợi ích tuyệt vời mà họ có thể kết hợp theo yêu cầu.

Vì vậy, mỗi người trong số các truy vấn sau đây sẽ sử dụng một hoặc nhiều các chỉ số:

select * from mytable where col1 = 10; 

select * from mytable where col2 = 10 and col3 = 16; 

select * from mytable where col3 = 16; 

Vì vậy, chỉ số bitmap có thể là một lựa chọn cho bạn. Tuy nhiên, như David Aldridge đã chỉ ra, tùy thuộc vào dữ liệu cụ thể của bạn thiết lập một chỉ mục duy nhất trên (col1, col2, col3) có thể thích hợp hơn. Như mọi khi, nó phụ thuộc. Hãy xem dữ liệu của bạn, các truy vấn có khả năng chống lại dữ liệu đó và đảm bảo thống kê của bạn được cập nhật.

Hy vọng điều này sẽ hữu ích.

+0

+1 Rất thú vị. Không biết mảng bitmap, nhưng http://en.wikipedia.org/wiki/Bitmap_index có một bài viết ngắn gọn về chúng. –

+1

Cẩn thận mặc dù - chỉ mục bitmap không vui lòng sửa đổi đồng thời, vì vậy chúng thường là một lựa chọn kém trong các hệ thống OLTP. –

+0

Đúng. Nghèo trong OLTP - tuyệt vời trong kho dữ liệu. "Như mọi khi, nó phụ thuộc". –

Các vấn đề liên quan