Khi nào và tại sao cơ sở dữ liệu tham gia đắt tiền?


354

Tôi đang thực hiện một số nghiên cứu về cơ sở dữ liệu và tôi đang xem xét một số hạn chế của DB quan hệ.

Tôi nhận được rằng tham gia của các bảng lớn là rất tốn kém, nhưng tôi không hoàn toàn chắc chắn tại sao. DBMS cần làm gì để thực hiện thao tác nối, nút thắt ở đâu?
Làm thế nào có thể không chuẩn hóa giúp khắc phục chi phí này? Làm thế nào để các kỹ thuật tối ưu hóa khác (lập chỉ mục, ví dụ) giúp đỡ?

Kinh nghiệm cá nhân đều được chào đón! Nếu bạn định đăng liên kết tới các tài nguyên, vui lòng tránh Wikipedia. Tôi biết nơi để tìm thấy nó.

Liên quan đến vấn đề này, tôi tự hỏi về các cách tiếp cận không chuẩn hóa được sử dụng bởi các cơ sở dữ liệu dịch vụ đám mây như BigTable và SimpleDB. Xem câu hỏi này .


3
Bạn cũng đang tìm kiếm những lợi ích? ;)
David Aldridge

Tôi đang xem xét một mục tiêu (nếu có một điều như vậy) so sánh. Pro, con, những gì bạn có.
Rik

Các cách tiếp cận được kết xuất trước của điện toán đám mây được khẳng định là có thể đặt cược mọi cách, tránh vấn đề "tham gia sai". Google có một số trang trắng trên hệ thống của riêng họ. Khá thú vị - cách để mở rộng khả năng áp dụng của các trường hợp đặc biệt.
Peter Wone

@PeterWone - quan tâm để cung cấp một tài liệu tham khảo cho một số các giấy tờ? Để trả lời câu hỏi trong hồ sơ của bạn, Android là Nguồn mở - tốt, ít nhất là một phần, do đó, các chuyên viên máy tính đã nhảy vào băng thông đó. Được xem là tiến bộ về mặt kỹ thuật bởi những người chưa được đào tạo tuyệt vời, họ đã được theo dõi như một cái ôm chặt chẽ và ướt đẫm mồ hôi của Google! Betamax có ai không? Gần gũi hơn với trái tim của tôi (và thế hệ), làm thế nào MySQL (không có FOREGIN KEYFFS) trở thành (và vẫn) DBMS "R" phổ biến nhất thế giới khi nó có sự cạnh tranh từ PostgreQuery (không có phiên bản Windows gốc) và Firebird (Opensource fiasco) hoặc thậm chí SQLite?
Vérace

Không cần phải nói, tôi coi PostgreSQL và Firebird như bao la vượt trội so với MySQL cho các hệ thống đa người dùng và SQLite như sao trong lĩnh vực sử dụng duy nhất. SQLite xử lý trang web sqlite.org (400,00 lượt truy cập mỗi ngày!).
Vérace

Câu trả lời:


470

Không chuẩn hóa để cải thiện hiệu suất? Nghe có vẻ thuyết phục, nhưng nó không giữ nước.

Chris Date, người hợp tác với Tiến sĩ Ted Codd là người đề xuất ban đầu của mô hình dữ liệu quan hệ, đã hết kiên nhẫn với các lập luận sai lệch chống lại bình thường hóa và phá hủy chúng một cách có hệ thống bằng phương pháp khoa học: ông đã có được cơ sở dữ liệu lớn và thử nghiệm các xác nhận này.

Tôi nghĩ anh ấy đã viết nó trong Relational Database Writings 1988-1991 nhưng cuốn sách này sau đó được cuộn lại thành phiên bản sáu Giới thiệu về Cơ sở dữ liệu hệ thống , đó là các văn bản dứt khoát về lý thuyết cơ sở dữ liệu và thiết kế, trong ấn bản thứ tám của nó như tôi viết và khả năng duy trì in trong nhiều thập kỷ tới. Chris Date là một chuyên gia trong lĩnh vực này khi hầu hết chúng ta vẫn chạy xung quanh chân đất.

Ông thấy rằng:

  • Một số trong số họ giữ cho các trường hợp đặc biệt
  • Tất cả đều thất bại trong việc sử dụng chung
  • Tất cả đều tồi tệ hơn đáng kể đối với các trường hợp đặc biệt khác

Tất cả quay trở lại để giảm thiểu kích thước của bộ làm việc. Các phép nối liên quan đến các khóa được chọn đúng với các chỉ mục được thiết lập chính xác là rẻ, không đắt, vì chúng cho phép cắt tỉa đáng kể kết quả trước khi các hàng được cụ thể hóa.

Cụ thể hóa kết quả liên quan đến việc đọc số lượng lớn đĩa là khía cạnh đắt nhất của bài tập theo một mức độ lớn. Thực hiện nối, ngược lại, logic chỉ yêu cầu truy xuất các phím . Trong thực tế, ngay cả các giá trị khóa cũng không được tìm nạp: các giá trị băm chính được sử dụng để so sánh nối, giảm thiểu chi phí của các phép nối nhiều cột và giảm triệt để chi phí của các phép nối liên quan đến so sánh chuỗi. Không chỉ phù hợp hơn với bộ nhớ cache, việc đọc đĩa còn ít hơn rất nhiều.

Hơn nữa, một trình tối ưu hóa tốt sẽ chọn điều kiện hạn chế nhất và áp dụng nó trước khi thực hiện phép nối, tận dụng rất hiệu quả tính chọn lọc cao của các phép nối trên các chỉ mục có độ chính xác cao.

Phải thừa nhận rằng loại tối ưu hóa này cũng có thể được áp dụng cho cơ sở dữ liệu không chuẩn hóa, nhưng loại người muốn không chuẩn hóa một lược đồ thường không nghĩ về cardinality khi (nếu) họ thiết lập các chỉ mục.

Điều quan trọng là phải hiểu rằng quét bảng (kiểm tra từng hàng trong một bảng trong quá trình tạo liên kết) là rất hiếm trong thực tế. Trình tối ưu hóa truy vấn sẽ chọn quét bảng chỉ khi một hoặc nhiều lần giữ sau đây.

  • Có ít hơn 200 hàng trong mối quan hệ (trong trường hợp này, quét sẽ rẻ hơn)
  • Không có chỉ mục phù hợp trên các cột tham gia (nếu tham gia vào các cột này có ý nghĩa thì tại sao chúng không được lập chỉ mục? Sửa nó)
  • Cần phải có một kiểu ép buộc trước khi các cột có thể được so sánh (WTF?! Sửa nó hoặc về nhà) XEM THÔNG BÁO KẾT THÚC CHO VẤN ĐỀ ADO.NET
  • Một trong những đối số của so sánh là một biểu thức (không có chỉ mục)

Thực hiện một hoạt động tốn kém hơn so với không thực hiện nó. Tuy nhiên, thực hiện sai thao tác, bị buộc vào đĩa vô nghĩa I / O và sau đó loại bỏ các cặn bã trước để thực hiện tham gia bạn thực sự có nhu cầu, là nhiều tốn kém hơn. Ngay cả khi hoạt động "sai" được tính toán trước và các chỉ mục đã được áp dụng hợp lý, vẫn có hình phạt đáng kể. Việc không chuẩn hóa để tính toán trước một tham gia - mặc dù có sự bất thường về cập nhật đòi hỏi - là một cam kết đối với một tham gia cụ thể. Nếu bạn cần một khác nhau tham gia, cam kết có nghĩa là sẽ chi phí bạn lớn .

Nếu bất cứ ai muốn nhắc nhở tôi rằng đó là một thế giới đang thay đổi, tôi nghĩ bạn sẽ thấy rằng các bộ dữ liệu lớn hơn trên phần cứng cứng hơn chỉ phóng đại sự lan truyền của những phát hiện của Date.

Đối với tất cả các bạn làm việc trên các hệ thống thanh toán hoặc trình tạo thư rác (xấu hổ về bạn) và đang phẫn nộ đặt bàn phím để nói với tôi rằng bạn biết rằng thực tế là việc không chuẩn hóa nhanh hơn, xin lỗi nhưng bạn đang sống trong một trong những điều đặc biệt trường hợp - cụ thể, trường hợp bạn xử lý tất cả dữ liệu, theo thứ tự. Đó không phải là một trường hợp chung, và bạn hợp lý trong chiến lược của bạn.

Bạn không được biện minh trong việc khái quát nó. Xem phần cuối của phần ghi chú để biết thêm thông tin về cách sử dụng không chuẩn hóa thích hợp trong các tình huống lưu trữ dữ liệu.

Tôi cũng muốn trả lời

Joins chỉ là sản phẩm cartesian với một số lipgloss

Thật là một tải bollocks. Hạn chế được áp dụng càng sớm càng tốt, hạn chế nhất trước tiên. Bạn đã đọc lý thuyết, nhưng bạn chưa hiểu nó. Tham gia được coi là "Tích Descartes mà các vị từ áp dụng" chỉ bởi optimizer truy vấn. Đây là một biểu diễn tượng trưng (trên thực tế là chuẩn hóa) để tạo điều kiện cho phân rã biểu tượng để trình tối ưu hóa có thể tạo ra tất cả các phép biến đổi tương đương và xếp hạng chúng theo chi phí và độ chọn lọc để có thể chọn kế hoạch truy vấn tốt nhất.

Cách duy nhất bạn sẽ có được trình tối ưu hóa để sản xuất một sản phẩm cartesian là không cung cấp một vị từ: SELECT * FROM A,B


Ghi chú


David Aldridge cung cấp một số thông tin bổ sung quan trọng.

Thực sự có một loạt các chiến lược khác ngoài các chỉ mục và quét bảng, và một trình tối ưu hóa hiện đại sẽ tiêu tốn tất cả trước khi đưa ra một kế hoạch thực hiện.

Một lời khuyên thực tế: nếu nó có thể được sử dụng như một khóa ngoại thì hãy lập chỉ mục cho nó, để chiến lược chỉ số có sẵn cho trình tối ưu hóa.

Tôi đã từng thông minh hơn trình tối ưu hóa MSSQL. Điều đó đã thay đổi hai phiên bản trước. Bây giờ nó thường dạy tôi . Theo một nghĩa rất thực, đó là một hệ thống chuyên gia, mã hóa tất cả sự khôn ngoan của nhiều người rất thông minh trong một lĩnh vực đủ khép kín rằng một hệ thống dựa trên quy tắc có hiệu quả.


"Bollocks" có thể đã được khéo léo. Tôi được yêu cầu bớt kiêu căng và nhắc nhở rằng toán học không nói dối. Điều này là đúng, nhưng không phải tất cả ý nghĩa của các mô hình toán học nhất thiết phải được thực hiện theo đúng nghĩa đen. Căn bậc hai của số âm rất tiện dụng nếu bạn cẩn thận tránh kiểm tra tính vô lý của chúng (chơi chữ ở đó) và chắc chắn rằng bạn hủy bỏ tất cả chúng trước khi bạn cố gắng giải thích phương trình của mình.

Lý do mà tôi trả lời rất dã man là vì câu nói như đã nói

Tham gia sản phẩm cartesian ...

Đây có thể không phải là những gì có nghĩa nhưng nó những gì đã được viết, và nó hoàn toàn không đúng sự thật. Một sản phẩm cartesian là một mối quan hệ. Tham gia là một chức năng. Cụ thể hơn, tham gia là một chức năng có giá trị quan hệ. Với một vị từ trống, nó sẽ tạo ra một sản phẩm cartesian và kiểm tra xem nó có phải là một kiểm tra chính xác cho một công cụ truy vấn cơ sở dữ liệu, nhưng không ai viết các phép nối không bị ràng buộc trong thực tế vì chúng không có giá trị thực tế bên ngoài lớp học.

Tôi gọi điều này vì tôi không muốn độc giả rơi vào cái bẫy cổ xưa gây nhầm lẫn mô hình với mô hình. Một mô hình là một xấp xỉ, cố tình đơn giản hóa để thao tác thuận tiện.


Việc cắt giảm để lựa chọn chiến lược nối bảng quét có thể khác nhau giữa các công cụ cơ sở dữ liệu. Nó bị ảnh hưởng bởi một số quyết định thực hiện, chẳng hạn như hệ số lấp đầy nút cây, kích thước giá trị khóa và độ tinh tế của thuật toán, nhưng nói chung, chỉ mục hiệu suất cao có thời gian thực hiện là k log n + c . Thuật ngữ C là một chi phí cố định chủ yếu được tạo ra từ thời gian thiết lập và hình dạng của đường cong có nghĩa là bạn không được trả tiền (so với tìm kiếm tuyến tính) cho đến khi n có hàng trăm.


Đôi khi không chuẩn hóa là một ý tưởng tốt

Không chuẩn hóa là một cam kết cho một chiến lược tham gia cụ thể. Như đã đề cập trước đó, điều này can thiệp vào các chiến lược tham gia khác . Nhưng nếu bạn có không gian đĩa, các kiểu truy cập có thể dự đoán được và xu hướng xử lý nhiều hoặc tất cả, thì việc tính toán trước một phép nối có thể rất đáng giá.

Bạn cũng có thể tìm ra các đường dẫn truy cập mà hoạt động của bạn thường sử dụng và tính toán trước tất cả các phép nối cho các đường dẫn truy cập đó. Đây là tiền đề đằng sau kho dữ liệu, hoặc ít nhất là khi chúng được xây dựng bởi những người biết tại sao họ làm những gì họ đang làm, và không chỉ vì mục đích tuân thủ từ thông dụng.

Kho dữ liệu được thiết kế đúng được tạo ra định kỳ bằng cách chuyển đổi hàng loạt ra khỏi hệ thống xử lý giao dịch được chuẩn hóa. Sự tách biệt giữa các hoạt động và cơ sở dữ liệu báo cáo này có tác dụng rất mong muốn là loại bỏ xung đột giữa OLTP và OLAP (xử lý giao dịch trực tuyến tức là nhập dữ liệu và xử lý phân tích trực tuyến tức là báo cáo).

Một điểm quan trọng ở đây là ngoài các bản cập nhật định kỳ, kho dữ liệu chỉ được đọc . Điều này làm cho câu hỏi về sự bất thường cập nhật.

Đừng phạm sai lầm khi không chuẩn hóa cơ sở dữ liệu OLTP của bạn (cơ sở dữ liệu mà việc nhập dữ liệu xảy ra). Nó có thể nhanh hơn cho việc chạy hóa đơn nhưng nếu bạn làm điều đó, bạn sẽ nhận được sự bất thường cập nhật. Bạn đã bao giờ cố gắng để Digest Digest ngừng gửi cho bạn công cụ chưa?

Dung lượng ổ đĩa rẻ trong những ngày này, vì vậy hãy tự đánh gục mình. Nhưng việc không chuẩn hóa chỉ là một phần của câu chuyện đối với kho dữ liệu. Tăng hiệu suất lớn hơn nhiều có được từ các giá trị cuộn lên được tính toán trước: tổng số hàng tháng, loại đó. Nó luôn luôn là về việc giảm tập làm việc.


Vấn đề ADO.NET với kiểu không khớp

Giả sử bạn có một bảng SQL Server chứa một cột kiểu varchar được lập chỉ mục và bạn sử dụng AddWithValue để truyền tham số ràng buộc một truy vấn trên cột này. Chuỗi C # là Unicode, vì vậy loại tham số được suy ra sẽ là NVARCHAR, không khớp với VARCHAR.

VARCHAR sang NVARCHAR là một chuyển đổi mở rộng để nó diễn ra hoàn toàn - nhưng hãy nói lời tạm biệt với việc lập chỉ mục và chúc may mắn tìm ra lý do tại sao.


"Đếm số lần truy cập đĩa" (Rick James)

Nếu mọi thứ được lưu trữ trong RAM, JOINsthì khá rẻ. Đó là, bình thường hóa không có nhiều hiệu suất phạt .

Nếu một lược đồ "chuẩn hóa" gây ra JOINsnhiều đĩa, nhưng lược đồ "không chuẩn hóa" tương đương sẽ không phải đánh vào đĩa, thì việc không chuẩn hóa sẽ thắng một cuộc cạnh tranh hiệu năng.

Nhận xét từ tác giả gốc: Các công cụ cơ sở dữ liệu hiện đại rất giỏi trong việc tổ chức tuần tự truy cập để giảm thiểu các lỗi bộ nhớ cache trong các hoạt động tham gia. Ở trên, trong khi sự thật, có thể bị hiểu sai vì ngụ ý rằng việc tham gia nhất thiết phải là vấn đề đắt đỏ trên dữ liệu lớn. Điều này sẽ dẫn đến việc ra quyết định kém về phía các nhà phát triển thiếu kinh nghiệm.


7
Sonme của những tuyên bố này là cụ thể cho một DBMS cụ thể, phải không? ví dụ. "Có ít hơn 200 hàng trong mối quan hệ"
David Aldridge

2
Việc sử dụng các khóa thay thế (hoặc không) có ảnh hưởng đáng kể đến tất cả điều này?
David Plumpton

3
Codd EF tuyệt vời chỉ chịu trách nhiệm cho Mô hình quan hệ. CJ Date, và gần đây là H Darwen, đều là những kẻ ngốc, những người không hiểu về RM và cung cấp hàng loạt thông tin về "cách cải thiện" RM, tất cả đều có thể bị loại bỏ, bởi vì người ta không thể sửa chữa những gì người ta không hiểu . Họ chỉ phục vụ để làm hỏng sự liên quan của RM, bằng cách gợi ý rằng có một cái gì đó "mất tích".
PerformanceDBA

7
Ngoài ra, đừng quên rằng nhiều cơ sở dữ liệu NoQuery về cơ bản là cùng một cơ sở dữ liệu mà chúng ta đã loại bỏ 40 năm trước. Những người trẻ tuổi luôn nghĩ rằng họ đã khám phá ra điều gì đó mới mẻ. Fabian Pascal: dbdebunk.com/2014/02/thinking-logical-sql-nosql-and.html
N West

3
Xâm lược. Đó là một tài khoản tốt, nhưng sự xâm lược và xâm lăng vi mô không thêm vào nội dung hoặc giá trị của nội dung.
MrMesees

46

Điều mà hầu hết các nhà bình luận không lưu ý là một loạt các phương pháp tham gia có sẵn trong một RDBMS phức tạp và những người không bình thường luôn phủ bóng lên chi phí cao hơn để duy trì dữ liệu không chuẩn hóa. Không phải mọi tham gia đều dựa trên các chỉ mục và cơ sở dữ liệu có rất nhiều thuật toán và phương pháp tối ưu hóa để tham gia nhằm giảm chi phí tham gia.

Trong mọi trường hợp, chi phí tham gia phụ thuộc vào loại của nó và một vài yếu tố khác. Nó không cần phải đắt tiền - một số ví dụ.

  • Một phép nối băm, trong đó dữ liệu số lượng lớn được cân bằng, thực sự rất rẻ và chi phí chỉ trở nên đáng kể nếu bảng băm không thể được lưu trong bộ nhớ. Không có chỉ số cần thiết. Phân vùng cân bằng giữa các bộ dữ liệu được tham gia có thể là một trợ giúp tuyệt vời.
  • Chi phí của một phép nối hợp nhất được điều khiển bởi chi phí của sắp xếp chứ không phải là hợp nhất - một phương thức truy cập dựa trên chỉ mục hầu như có thể loại bỏ chi phí của sắp xếp.
  • Chi phí của phép nối vòng lặp lồng nhau trên một chỉ mục được điều khiển bởi chiều cao của chỉ số cây b và quyền truy cập của chính khối bảng. Nó nhanh, nhưng không phù hợp để tham gia số lượng lớn.
  • Một phép nối vòng lặp lồng nhau dựa trên một cụm rẻ hơn rất nhiều, với ít yêu cầu IO logic hơn cho mỗi hàng tham gia - nếu các bảng được nối đều nằm trong cùng một cụm thì phép nối trở nên rất rẻ thông qua việc sắp xếp các hàng được nối.

Cơ sở dữ liệu được thiết kế để tham gia và chúng rất linh hoạt trong cách chúng thực hiện và thường rất hiệu quả trừ khi chúng có cơ chế tham gia sai.


Tôi nghĩ rằng nó đi xuống "nếu nghi ngờ, hãy hỏi DBA của bạn". Cơ sở dữ liệu hiện đại là những con thú phức tạp và đòi hỏi phải nghiên cứu để hiểu. Tôi chỉ sử dụng Oracle từ năm 1996 và đây là công việc toàn thời gian theo kịp các tính năng mới. SQLserver cũng đã xuất hiện rất nhiều từ năm 2005. Đây không phải là một hộp đen!
Chàng trai

2
Hmmm, theo kinh nghiệm khiêm tốn của tôi, có quá nhiều DBA ngoài kia chưa bao giờ nghe nói về việc tham gia băm, hoặc nghĩ rằng họ là một điều xấu toàn cầu.
David Aldridge

28

Tôi nghĩ rằng toàn bộ câu hỏi được dựa trên một tiền đề sai. Tham gia trên các bàn lớn không nhất thiết phải đắt tiền. Trong thực tế, thực hiện tham gia hiệu quả là một trong những lý do chính khiến cơ sở dữ liệu quan hệ tồn tại. Tham gia trên các bộ lớn thường rất tốn kém, nhưng rất hiếm khi bạn muốn tham gia toàn bộ nội dung của bảng lớn A với toàn bộ nội dung của bảng lớn B. Thay vào đó, bạn viết truy vấn sao cho chỉ các hàng quan trọng của mỗi bảng được sử dụng và bộ thực tế được giữ bởi tham gia vẫn nhỏ hơn.

Ngoài ra, bạn có các hiệu quả được đề cập bởi Peter Wone, sao cho chỉ những phần quan trọng của mỗi bản ghi cần có trong bộ nhớ cho đến khi tập kết quả cuối cùng được cụ thể hóa. Ngoài ra, trong các truy vấn lớn có nhiều phép nối mà bạn thường muốn bắt đầu với các tập hợp bảng nhỏ hơn và thực hiện theo cách của bạn đến các bảng lớn, sao cho tập hợp được giữ trong bộ nhớ vẫn nhỏ nhất có thể.

Khi được thực hiện đúng cách, các phép nối thường là cách tốt nhất để so sánh, kết hợp hoặc lọc trên một lượng lớn dữ liệu.


1
@joel. Các ngược lại cũng đúng. Tham gia tập dữ liệu lớn có thể tốn kém và đôi khi được yêu cầu, nhưng bạn không muốn làm điều đó quá thường xuyên trừ khi a) bạn có thể xử lý IO và RAM cần thiết và b) bạn không làm việc đó quá thường xuyên. Xem xét các quan điểm cụ thể, hệ thống báo cáo, báo cáo thời gian thực so với CoB.
Chàng trai

11

Nút thắt khá nhiều luôn là I / O đĩa, và thậm chí cụ thể hơn - I / O đĩa ngẫu nhiên (bằng cách so sánh, các lần đọc tuần tự khá nhanh và có thể được lưu trong bộ đệm với các chiến lược đọc trước).

Tham gia có thể tăng tìm kiếm ngẫu nhiên - nếu bạn đang nhảy xung quanh đọc các phần nhỏ của một bảng lớn. Nhưng, các trình tối ưu hóa truy vấn tìm kiếm điều đó và sẽ biến nó thành quét bảng tuần tự (loại bỏ các hàng không cần thiết) nếu nó nghĩ rằng điều đó sẽ tốt hơn.

Một bảng không chuẩn hóa duy nhất có một vấn đề tương tự - các hàng lớn và do đó ít phù hợp hơn trên một trang dữ liệu. Nếu bạn cần các hàng nằm cách xa nhau (và kích thước hàng lớn làm cho chúng cách xa nhau hơn) thì bạn sẽ có thêm I / O ngẫu nhiên. Một lần nữa, quét bảng có thể bị buộc phải tránh điều này. Nhưng, lần này, quét bảng của bạn phải đọc thêm dữ liệu vì kích thước hàng lớn. Thêm vào đó là thực tế rằng bạn đang sao chép dữ liệu từ một vị trí sang nhiều vị trí và RDBMS có nhiều thứ hơn để đọc (và bộ đệm).

Với 2 bảng, bạn cũng nhận được 2 chỉ mục được nhóm - và thường có thể lập chỉ mục nhiều hơn (vì chi phí chèn / cập nhật ít hơn) có thể giúp bạn tăng hiệu suất đáng kể (chủ yếu, một lần nữa, vì các chỉ mục (tương đối) nhỏ, nhanh chóng đọc được đĩa (hoặc rẻ để lưu vào bộ đệm) và giảm số lượng hàng trong bảng bạn cần đọc từ đĩa).

Về chi phí duy nhất với một liên kết đến từ việc tìm ra các hàng phù hợp. Sql Server sử dụng 3 loại liên kết khác nhau, chủ yếu dựa trên kích thước tập dữ liệu, để tìm các hàng khớp. Nếu trình tối ưu hóa chọn loại tham gia sai (do số liệu thống kê không chính xác, chỉ mục không đầy đủ hoặc chỉ là lỗi tối ưu hóa hoặc trường hợp cạnh), nó có thể ảnh hưởng mạnh đến thời gian truy vấn.

  • Một tham gia vòng lặp là cực kỳ rẻ cho (ít nhất 1) tập dữ liệu nhỏ.
  • Một phép nối hợp nhất đòi hỏi một loại cả hai tập dữ liệu trước. Tuy nhiên, nếu bạn tham gia vào một cột được lập chỉ mục, thì chỉ mục đã được sắp xếp và không cần thực hiện thêm công việc nào nữa. Mặt khác, có một số chi phí CPU và bộ nhớ trong sắp xếp.
  • Phép nối băm yêu cầu cả bộ nhớ (để lưu trữ hàm băm) và CPU (để xây dựng hàm băm). Một lần nữa, điều này khá nhanh liên quan đến I / O của đĩa. Tuy nhiên , nếu không đủ RAM để lưu trữ hashtable, Sql Server sẽ sử dụng tempdb để lưu trữ các phần của hashtable và các hàng tìm thấy, sau đó chỉ xử lý các phần của hashtable tại một thời điểm. Như với tất cả mọi thứ đĩa, điều này là khá chậm.

Trong trường hợp tối ưu, những nguyên nhân này không có I / O đĩa - và do đó không đáng kể từ góc độ hiệu suất.

Nói chung, tệ nhất - thực sự nên đọc nhanh hơn cùng một lượng dữ liệu lôgic từ các bảng đã tham gia x, vì nó là từ một bảng không chuẩn hóa do các đĩa nhỏ hơn đọc. Để đọc cùng một lượng dữ liệu vật lý , có thể có một chút chi phí nhỏ.

Vì thời gian truy vấn thường bị chi phối bởi chi phí I / O và kích thước dữ liệu của bạn không thay đổi (trừ một số chi phí hàng rất nhỏ) với việc không chuẩn hóa, nên không có lợi ích to lớn nào khi chỉ hợp nhất các bảng với nhau. Loại không chuẩn hóa có xu hướng tăng hiệu suất, IME, là lưu các giá trị được tính toán thay vì đọc 10.000 hàng cần thiết để tính toán chúng.


Giảm tìm kiếm ngẫu nhiên: điểm tốt, mặc dù bộ điều khiển RAID tốt với bộ đệm lớn sẽ thực hiện đọc / ghi thang máy.
Peter Wone

3

Thứ tự mà bạn tham gia các bảng là vô cùng quan trọng. Nếu bạn có hai bộ dữ liệu, hãy cố gắng xây dựng truy vấn theo cách sao cho nhỏ nhất sẽ được sử dụng trước tiên để giảm lượng dữ liệu mà truy vấn phải thực hiện.

Đối với một số cơ sở dữ liệu, điều đó không thành vấn đề, ví dụ MS SQL không biết thứ tự tham gia phù hợp hầu hết thời gian. Đối với một số người (như IBM Informix), đơn hàng tạo ra sự khác biệt.


1
Nói chung, trình tối ưu hóa truy vấn khá sẽ không bị ảnh hưởng bởi thứ tự các phép nối hoặc bảng được liệt kê và sẽ tự xác định cách thức hiệu quả nhất để thực hiện phép nối.
David Aldridge

5
MySQL, Oracle, SQL Server, Sybase, postgreSQL, v.v. quan tâm không theo thứ tự tham gia. Tôi đã làm việc với DB2 và theo hiểu biết của tôi, tôi không quan tâm bạn đặt chúng theo thứ tự nào. Đây không phải là lời khuyên hữu ích trong trường hợp chung
Matt Rogish

Phân cụm MySQL sử dụng công cụ NDB (phải thừa nhận là trường hợp biên và chỉ các nhà phát triển nâng cao sẽ đến gần NDB) không đoán đúng thứ tự tham gia, vì vậy bạn phải thêm câu lệnh "USE INDEX" vào hầu hết các truy vấn đã tham gia nếu không không hiệu quả khủng khiếp. Tài liệu MySQL bao gồm nó.
joelhardi

@iiya, Hiểu những gì trình tối ưu hóa sẽ chọn là quan trọng hơn các tuyên bố chung chung hoặc "huyền thoại" về thứ tự bảng. Không dựa vào một cách giải quyết cụ thể trong SQL của bạn vì hành vi thường thay đổi khi RDBMS được nâng cấp. Oracle đã thay đổi hành vi nhiều lần kể từ v7.
Chàng trai

1
@Matt Tôi đã thấy Oracle 9i thực hiện các kế hoạch truy vấn và tối ưu hóa rất khác nhau chỉ bằng cách điều chỉnh thứ tự tham gia. Có lẽ điều này đã thay đổi từ phiên bản 10i trở đi?
Camilo Díaz Repka

0

Quyết định xem có nên chuẩn hóa hoặc chuẩn hóa hay không là một quá trình đơn giản khi bạn xem xét lớp phức tạp của phép nối. Chẳng hạn, tôi có xu hướng thiết kế cơ sở dữ liệu của mình với chuẩn hóa khi các truy vấn là O (k log n) trong đó k liên quan đến cường độ đầu ra mong muốn.

Một cách dễ dàng để không chuẩn hóa và tối ưu hóa hiệu suất là suy nghĩ về cách thay đổi cấu trúc chuẩn hóa của bạn ảnh hưởng đến cấu trúc không chuẩn hóa của bạn. Tuy nhiên, nó có thể có vấn đề vì nó có thể yêu cầu logic giao dịch để làm việc trên một cấu trúc không chuẩn hóa.

Cuộc tranh luận về bình thường hóa và không chuẩn hóa sẽ không kết thúc vì các vấn đề là rất lớn. Có nhiều vấn đề trong đó giải pháp tự nhiên đòi hỏi cả hai cách tiếp cận.

Theo nguyên tắc chung, tôi luôn lưu trữ một cấu trúc chuẩn hóa và bộ đệm không chuẩn hóa có thể được xây dựng lại. Cuối cùng, những bộ nhớ cache này lưu ass của tôi để giải quyết các vấn đề bình thường hóa trong tương lai.


-8

Xây dựng những gì người khác đã nói,

Joins chỉ là sản phẩm cartesian với một số lipgloss. {1,2,3,4} X {1,2,3} sẽ cung cấp cho chúng tôi 12 kết hợp (nXn = n ^ 2). Bộ tính toán này hoạt động như một tài liệu tham khảo về các điều kiện được áp dụng. DBMS áp dụng các điều kiện (như cả hai bên trái và phải là 2 hoặc 3) để cung cấp cho chúng tôi (các) điều kiện khớp. Trên thực tế nó được tối ưu hóa hơn nhưng vấn đề là như nhau. Thay đổi kích thước của các bộ sẽ tăng kích thước kết quả theo cấp số nhân. Số lượng bộ nhớ và chu kỳ cpu tiêu thụ tất cả được thực hiện theo thuật ngữ hàm mũ.

Khi chúng tôi không bình thường, chúng tôi sẽ tránh tính toán này hoàn toàn, hãy nghĩ đến việc có một miếng dính màu, được đính kèm trên mỗi trang của cuốn sách của bạn. Bạn có thể suy ra thông tin bằng cách sử dụng một tài liệu tham khảo. Hình phạt mà chúng tôi phải trả là chúng tôi đang làm tổn hại đến bản chất của DBMS (tổ chức dữ liệu tối ưu)


3
-1: Bài đăng này là một ví dụ tuyệt vời về lý do tại sao bạn để DBMS thực hiện các phép nối - bởi vì các nhà thiết kế DBMS luôn nghĩ về những vấn đề này và đưa ra những cách hiệu quả hơn để làm điều đó hơn phương pháp compsci 101.
David Aldridge

2
@David: Đồng ý. Lập trình viên tối ưu hóa DBMS là một số cookie thông minh
Matt Rogish

Câu trả lời này không chính xác. Nếu truy vấn của bạn được thực thi đối với cơ sở dữ liệu được lập chỉ mục, được chuẩn hóa và có bất kỳ loại bộ lọc hoặc điều kiện nối nào, trình tối ưu hóa sẽ tìm cách tránh sản phẩm Cartesian và giảm thiểu việc sử dụng bộ nhớ và chu kỳ CPU. Nếu bạn thực sự có ý định chọn một sản phẩm của Cartesian, bạn sẽ sử dụng cùng một bộ nhớ trong db đã chuẩn hóa hoặc không chuẩn hóa.
rileymcdowell
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.