2012-01-01 20 views
6

Nói chung ... nên tham gia bảng (tức là bảng kết hợp) được tạo dưới dạng Bảng tổ chức chỉ mục (Oracle), Chỉ mục được nhóm (SQL Server) .... hoặc bảng heap cũ (với chỉ mục riêng biệt trên 2 cột).Các bảng tham gia có nên được tạo ra dưới dạng các bảng có tổ chức chỉ mục (chỉ mục được nhóm) không?

Cách tôi xem liệu các ưu điểm có:

Cải thiện tốc độ. Bạn đang tránh một bảng heap tra cứu.

Cải tiến không gian. Bạn đang loại bỏ hoàn toàn bảng heap, vì vậy bạn có thể tiết kiệm ~ 30% dung lượng.

Những khó khăn:

Index Skip Scan (chỉ áp dụng cho Oracle) .. sẽ nhanh hơn sau đó một Full Bảng Scan, nhưng chậm hơn sau đó một Scan Index. Vì vậy, các tìm kiếm trên cột thứ hai của khóa phức hợp sẽ chậm hơn một chút (Oracle), chậm hơn nhiều (MSSQL).

Quét toàn bộ chỉ mục sẽ chậm hơn sau đó quét toàn bộ bảng - vì vậy nếu hầu hết thời gian Trình tối ưu hóa chi phí đang thực hiện Hash Join (không tận dụng lợi thế của chỉ mục) ... bạn có thể mong đợi hiệu suất kém hơn. (Giả sử RDBMS không lọc các bảng lần đầu tiên).

Điều này làm cho tôi đặt câu hỏi liệu có bất kỳ loại chỉ mục nào thực sự được yêu cầu cho Bảng tham gia hay không, nếu bạn chủ yếu thực hiện Hash Join.

+0

Bạn phải có khóa chính kết hợp trên 2 cột sẽ tạo chỉ mục duy nhất trên chúng. –

+2

reg "Quét toàn bộ chỉ mục sẽ chậm hơn sau đó quét toàn bộ bảng": Oracle cũng có INDEX FAST FULL SCAN cơ bản nhanh như truy cập bảng đầy đủ. Xem http://use-the-index-luke.com/sql/explain-plan/oracle/operations#index_fast_full_scan. Xem thêm bình luận của tôi reg. Hash Tham gia lập chỉ mục bên dưới. –

+0

@MarkusWinand - Điểm tốt ... Cảm ơn các trang web tuyệt vời (IMO nó là dbms ngắn gọn nhất bất khả tri nguồn trên các chỉ mục trực tuyến). – vicsz

Trả lời

3

Quy tắc cá nhân của tôi là tạo các thực thể liên kết hai bảng dưới dạng bảng được chỉ mục, với ràng buộc khóa chính là "hướng" truy cập mà tôi mong muốn được sử dụng phổ biến hơn. Sau đó, tôi sẽ thường thêm một chỉ mục duy nhất để bao gồm thứ tự đảo ngược của các khóa, vì vậy trong mọi trường hợp, trình tối ưu hóa sẽ có thể sử dụng truy cập quét độc lập hoặc quét dải.

Ba bảng (hoặc nhiều) đối tượng liên kết thường yêu cầu phân tích nhiều hơn đáng kể.

Ngoài ra, trình tối ưu hóa sẽ sử dụng các chỉ mục có hoạt động nối băm; thường quét nhanh toàn bộ, tuy nhiên chỉ mục.

3

Tôi chỉ liệt kê và nói chuyện qua một vài giải pháp khả thi, hy vọng sẽ giúp bạn quyết định. "Bảng công đoàn" chứa hai hoặc ba cột. Khóa ngoài ở bảng bên trái, hãy nói a và khóa ngoài ở bên phải bảng, hãy nói b. Cột tùy chọn là danh tính hàng cho "bảng kết hợp", nói id.

Giải pháp 1: Cột a,b. Không có chỉ mục nhóm (heap), chỉ mục trên (a,b)(b,a)
Cả hai cột được lưu trữ ở ba vị trí. Nó hỗ trợ tìm kiếm trên cả hai ab và tìm kiếm b không yêu cầu tra cứu dấu trang, kể từ a một phần của chỉ mục (b,a). Sự lựa chọn phong phú, nhưng bộ nhớ ba dường như là một sự lãng phí. Heap không sử dụng nhưng phải được duy trì trong các truy vấn insertupdate.

Giải pháp 2: Cột a, b. Chỉ mục được nhóm trên (a,b), chỉ mục trên (b,a)
Tất cả dữ liệu được lưu trữ hai lần. Có thể phục vụ tìm kiếm trên ab mà không cần tra cứu dấu trang. Đây sẽ là phương pháp thực hành tốt nhất. Nó giao dịch lưu trữ đĩa cho tốc độ.

Giải pháp 3: Cột a, b. Chỉ mục được nhóm trên (a,b)
Tất cả dữ liệu chỉ được lưu trữ một lần. Nó có thể phục vụ một tìm kiếm trên a, nhưng không phải trên b. Đi từ bên phải sang bảng bên trái sẽ yêu cầu quét bảng. Điều này giao dịch tốc độ cho không gian đĩa. (Câu hỏi của bạn đề cập đến tham gia băm. Một băm tham gia luôn quét toàn bộ.)

Giải pháp 4: Cột id, a, b.Chỉ mục được nhóm (id), chỉ mục trên (a)(b)
Tìm kiếm trên a hoặc b đều yêu cầu tra cứu dấu trang. Cả hai ab được lưu trữ hai lần trên đĩa, một lần trong chỉ mục của riêng chúng và một lần trong khóa được nhóm. Đây là giải pháp tồi tệ nhất mà tôi có thể nghĩ đến.

Danh sách này không có nghĩa là đầy đủ. Giải pháp 2 sẽ là lựa chọn mặc định tốt. Tôi sẽ đi cho điều đó, trừ khi một giải pháp khác chứng minh bản thân nó là tốt hơn đáng kể trong các bài kiểm tra.

+1

đã đồng ý, ngoại trừ thingy hash-join. Tham gia băm có thể sử dụng các chỉ mục cho độc lập với các vị từ. Có lẽ không có độc lập, nơi các biến vị ngữ trong một phép nối như vậy, sao cho câu lệnh có thể đúng cho trường hợp này. Nhưng nó phụ thuộc vào truy vấn thực tế. Xem http://use-the-index-luke.com/sql/join/hash-join-partial-objects –

+0

@Andomar: Tôi thích phân tích. Làm thế nào về một hiệp hội 3 bảng? Các chỉ mục trên '(a, b, c) - nhóm',' (b, c, a) 'và' (c, a, b) 'có được không? –

0

Tôi không quen thuộc với thuật ngữ Oracle, nhưng đối với SQL Server, câu hỏi được diễn đạt theo cách gây nhầm lẫn. Để làm rõ:

  • Một nhóm chỉ số xác định thứ tự vật lý của các bảng
  • Một chỉ số nonclustered về cơ bản là một bản sao của bảng chính, sắp xếp theo các phím giao
  • Bạn có thể gán ("bao gồm") các cột bổ sung trong chỉ mục nonclustered, có thể cho phép trình tối ưu hóa truy vấn sử dụng các cột đó để đáp ứng các truy vấn, thay vì thực hiện tra cứu dấu trang.
  • Heap là bảng không có chỉ mục thuộc bất kỳ loại nào. Tất cả các truy vấn đến một đống yêu cầu quét.
  • Quét toàn bộ chỉ số không độc quyền nhanh hơn quét toàn bộ bảng, miễn là chỉ mục hẹp hơn bảng và bạn không cần tra cứu dấu trang.

Vì vậy, với ý nghĩ đó, các khóa được sử dụng cho các kết nối thường phải có chỉ mục nhóm hoặc không được kết hợp với chúng, để tránh quét bảng. Bạn có thể bao gồm các cột bổ sung trong các chỉ mục nonclustered của bạn khi cần - và thích các chỉ mục nhóm cho các truy vấn bao gồm một phạm vi tiếp giáp của các giá trị khóa có quyền truy cập vào nhiều cột trên mỗi hàng.

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