2010-03-13 15 views
9

Trong ứng dụng của chúng tôi, chúng tôi thu thập dữ liệu về hiệu suất động cơ ô tô - về cơ bản là dữ liệu nguồn về hiệu suất động cơ dựa trên loại động cơ, xe chạy và thiết kế động cơ. Hiện tại, cơ sở cho chèn hàng mới là thời gian tắt động cơ; chúng tôi theo dõi các biến hiệu suất dựa trên sự thay đổi trạng thái động cơ từ hoạt động thành không hoạt động và ngược lại. Các engineState bảng có liên quan như sau:Trong MySQL, thiết kế truy vấn hiệu quả nhất để gia nhập các bảng lớn với nhiều mối quan hệ giữa các biến vị ngữ nối là gì?

+---------+-----------+---------------+---------------------+---------------------+-----------------+ 
| vehicle | engine | engine_state | state_start_time | state_end_time  | engine_variable | 
+---------+-----------+---------------+---------------------+---------------------+-----------------+ 
| 080025 | E01  | active  | 2008-01-24 16:19:15 | 2008-01-24 16:24:45 |    720 | 
| 080028 | E02  | inactive  | 2008-01-24 16:19:25 | 2008-01-24 16:22:17 |    304 | 
+---------+-----------+---------------+---------------------+---------------------+-----------------+ 

Đối với một phân tích cụ thể, chúng tôi muốn phân tích nội dung bảng dựa trên một granularity hàng phút, chứ không phải là cơ sở hiện hành của nhà nước động cơ hoạt động/không hoạt động. Đối với điều này, chúng tôi đang nghĩ đến việc tạo một bảng đơn giản productionMinute với một hàng cho mỗi phút trong giai đoạn chúng tôi đang phân tích và tham gia các bảng productionMinuteengineEvent trên cột ngày-thời gian trong mỗi bảng. Vì vậy, nếu giai đoạn phân tích của chúng tôi là từ 2009-12-01 đến 2010-02-28, chúng tôi sẽ tạo một bảng mới với 129.600 hàng, một cho mỗi phút mỗi ngày trong khoảng thời gian ba tháng đó. Vài hàng đầu tiên của bảng productionMinute:

+---------------------+ 
| production_minute | 
+---------------------+ 
| 2009-12-01 00:00 | 
| 2009-12-01 00:01 | 
| 2009-12-01 00:02 |  
| 2009-12-01 00:03 | 
+---------------------+ 

sự tham gia giữa các bảng sẽ là:

 FROM engineState AS es 
LEFT JOIN productionMinute AS pm ON pm.production_minute >= es.state_start_time 
           AND pm.production_minute <= es.event_end_time 

này tham gia, tuy nhiên, sẽ trả về nhiều vấn đề môi trường:

  1. các engineState bảng có 5 triệu hàng và bảng productionMinute có 130.000 hàng
  2. Khi một engineState hàng kéo dài hơn một phút (tức là sự khác biệt giữa es.state_start_timees.state_end_time lớn hơn một phút), như là trường hợp trong ví dụ trên, có rất nhiều hàng productionMinute bảng mà tham gia vào một hàng engineState bảng duy nhất
  3. Khi có nhiều hơn một động cơ đang hoạt động trong bất kỳ cho phút, cũng như mỗi ví dụ trên, nhiều engineState hàng bảng tham gia vào một productionMinute hàng duy nhất

Trong thử nghiệm luận lý của chúng tôi và chỉ sử dụng một chiết xuất bàn nhỏ (một ngày nào đó chứ không phải là 3 tháng, cho bảng productionMinute) truy vấn mất hơn một giờ để tạo. Trong nghiên cứu mục này để cải thiện hiệu suất để có thể truy vấn ba tháng dữ liệu, suy nghĩ của chúng tôi là tạo một bảng tạm thời từ bảng engineEvent, loại bỏ bất kỳ dữ liệu bảng nào không quan trọng cho phân tích và tham gia bảng tạm thời cho bảng productionMinute. Chúng tôi cũng đang có kế hoạch thử nghiệm với các kết nối khác nhau - đặc biệt là sự tham gia bên trong - để xem liệu điều đó có cải thiện hiệu suất hay không.

Thiết kế truy vấn tốt nhất để nối các bảng với nhiều: nhiều mối quan hệ giữa các biến vị ngữ nối như được nêu ở trên là gì? Loại kết nối tốt nhất (trái/phải, bên trong) là gì?

+0

Ví dụ cụ thể về loại báo cáo bạn đang cố tạo sẽ giúp ích gì. Nó là khá có thể là bạn không cần phải mở rộng vào quan sát mỗi phút và có thể xây dựng kết quả của bạn trực tiếp. Ngoài ra, bạn có chỉ mục nào trên bảng engineState của mình? – Martin

+0

Khiếu nại số 2 và 3 của bạn không phải là vấn đề môi trường, chúng là vấn đề thiết kế. Điều tôi muốn nói là tôi không thể thấy bất cứ điều gì sai trái với một trong hai điều đó - chúng đúng bởi vì bạn đã đặt ra dữ liệu của bạn theo cách đó. Bạn cần mô tả lý do tại sao bạn thấy đó là một vấn đề và làm cho nó rõ ràng những gì bạn mong đợi từ việc tham gia mà bạn đã viết (ý nghĩa ngữ nghĩa nào bạn muốn gán cho nó: D). – Unreason

Trả lời

0

Hiệu suất sẽ phụ thuộc vào cách dữ liệu của bạn trong bảng được cấu trúc.

kết nối bên ngoài trái hoặc phải chỉ hữu ích nếu bạn muốn tất cả các giá trị trong bảng bên trái hoặc bên phải cho phép chiếu đã chọn và các giá trị đó có thể không có thứ gì đó trong bảng được nối.

Tin tưởng Trình tối ưu hóa truy vấn của bạn để tìm thuật toán kết hợp hiệu quả nhất cho dữ liệu của bạn ... nó được xây dựng để biết cách thực hiện tốt công việc của nó.Nếu bạn có vấn đề về hiệu suất, hãy xem cách dữ liệu được cấu trúc và lưu trữ.

+0

Cảm ơn Jeremy; nhưng đó chính xác là câu hỏi mà tôi hỏi - chúng ta nên làm thế nào để cấu trúc và lưu trữ dữ liệu trong bảng để tối ưu hóa hiệu năng truy vấn khi làm việc thông qua nhiều mối quan hệ giữa các biến vị ngữ nối và làm việc với các tập dữ liệu lớn? Hãy nhớ rằng chúng tôi không gắn với thiết kế hiện tại của chúng tôi vì chúng tôi có thể sử dụng bảng tạm thời để cơ cấu lại dữ liệu và đưa các chỉ mục vào vị từ nối ... nhưng đây có phải là phương pháp làm việc cho những người khác phải đối mặt với thử thách hiệu suất tương tự không? Nếu không, phương pháp tiếp cận đã làm việc là gì? – lighthouse65

+0

Nhưng đó không phải là câu hỏi mà bạn đã hỏi. Bạn đã hỏi cụ thể về các lần tham gia. Nếu bạn có tập dữ liệu rất lớn và bạn có nhiều trường mà bạn muốn lập chỉ mục, tốt nhất là sử dụng cây B + để lập chỉ mục các trường của bạn. Nó sẽ yêu cầu ít IO hơn trong hầu hết các trường hợp khi thực hiện một truy vấn. Tôi không chắc chắn bao nhiêu điều khiển MySQL cung cấp cho bạn các kỹ thuật lập chỉ mục mà bạn có thể sử dụng, nhưng nếu bạn có lựa chọn, hãy chọn điều đó. Nếu bạn không có sự lựa chọn, sau đó tôi nghi ngờ nó sử dụng B + Trees để lập chỉ mục đã được và chỉ định một trường được lập chỉ mục sẽ bao gồm bạn. – joejoeson

+0

Cảm ơn bạn đã gửi lại Jeremy. Tôi tin rằng MySQL cho phép chúng tôi chỉ định loại chỉ mục để sử dụng. Chúng tôi sẽ xem xét tùy chọn này hơn nữa, tôi sẽ đăng lại những gì chúng tôi tìm thấy. – lighthouse65

1

hiệu suất thu hồi dữ liệu là chức năng của

  • tốc độ truy cập vào các dữ liệu trên đĩa (phụ thuộc về sự tồn tại của các chỉ số, kích thước của bảng, kích thước của bộ nhớ cache, tôi thô/O tốc độ)
  • số hồ sơ mà cần phải được trả lại (một số gia nhập giảm số hàng trả lại, một số tăng, một số điều kiện có thể được áp dụng trên chỉ số phải đến các hồ sơ)
  • số cột mà bạn cần phải trả lại

Đối với tất cả các bạn có thể tối ưu hóa

  • chỉ thêm
  • giảm kích thước của bảng bằng cách phân vùng đó theo chiều dọc (chia bảng vào hai hoặc nhiều bảng ngữ nghĩa khác nhau - ví dụ nếu từ bảng 5m của bạn, bạn thực sự chỉ làm việc với 100k bản ghi 99,5% thời gian có thể bạn có thể chia bảng thành hoạt động/không hoạt động hoặc tương tự)
  • cung cấp bạn không thể chia theo chiều dọc bạn có thể chia bảng theo chiều ngang - số cột mà cũng ảnh hưởng đến tốc độ truy xuất (nhưng không nhiều)
  • cuối cùng cải thiện tốc độ I/O thô có thể đạt được bằng cách tách bảng trong suốt trên nhiều đĩa cứng (nhưng biết các thuộc tính hệ thống tệp cơ bản của bạn)

Các chỉ mục có tác động lớn nhất đến hiệu suất vì chúng có thể giảm thời gian truy cập đĩa và tốc độ hoạt động bộ nhớ theo thứ tự độ lớn (chúng chuyển O (n) thành log O (n) với chi phí bảo trì cấu trúc chỉ mục; do đó, họ làm chậm cập nhật)

Để có chỉ mục tốc độ truy xuất tối đa phải bao gồm tất cả tham gia và điều kiện và truy vấn cần được viết theo cách mà trình tối ưu hóa truy vấn có thể xác định lợi ích nào sẽ mang lại lợi ích cao nhất nếu được thực hiện trước tiên chọn lọc).

Ví dụ cụ thể của bạn cố gắng kết hợp khác nhau chuẩn của chỉ số

  1. pm.production_minute nên được lập chỉ mục cho chắc chắn
  2. với es.state_start_time và es.state_end_time bạn có 4 tùy chọn chỉ số có thể (mà bạn có thể kết hợp):
    chỉ mục trên es.state_start_time index
    trên es.state_end_time index
    trên (es.state_start_time, es.state_end_time)
    chỉ số trên (es.state_end_time , es.state_start_time)

Biết dữ liệu của bạn sẽ cho phép bạn xác định cái nào là tối ưu. Tôi sẽ không ngạc nhiên nếu bạn thấy rằng có hai chỉ mục hai cột cuối cùng sẽ hoạt động tốt nhất. Hoặc có một cột đơn và một chỉ mục hai cột khác (nhưng theo thứ tự ngược lại của các cột).

Trong cả hai trường hợp này, trình tối ưu hóa sẽ có thể xác định kết quả từ chỉ đọc các chỉ mục và thậm chí không xem các bản ghi thực tế và giảm đáng kể truy cập đĩa của bạn.

0

Trải nghiệm của tôi là trình tối ưu hóa truy vấn MySQL khá tệ. Một trong PostgreSQL là tốt hơn nhiều.

Vấn đề của bạn là dữ liệu của bạn được cấu trúc để dễ dàng ghi, chứ không phải để dễ phân tích. Đề nghị của tôi là bạn đi trước và tạo ra bảng tạm thời, nhưng không phải là cách bạn có thể tưởng tượng. Tôi nghĩ rằng đặt cược tốt nhất của bạn là có bước hậu xử lý vào cuối mỗi ngày, lấy tất cả dữ liệu trong ngày và tạo các mục từng phút vào một bảng mới (lý tưởng trên trục chính khác) với chỉ mục production_minute. Cơ sở dữ liệu mới này sẽ nhanh hơn để thực hiện các truy vấn phân tích của bạn và các truy vấn sẽ không làm chậm đáng kể việc thu thập dữ liệu.

1

Tôi đồng ý với vy32. Bạn cần phải thực hiện truy vấn này một lần và chỉ một lần để có được dữ liệu của bạn ở định dạng phù hợp để phân tích. Bạn nên sử dụng một công cụ ETL thích hợp (hoặc heck, chỉ perl hoặc một cái gì đó đơn giản) để lấy dữ liệu ra khỏi bảng engineState, tính toán phút sản xuất, sau đó tải nó vào một DB khác mô hình đúng cho các truy vấn kiểu phân tích.

Nếu bạn nghĩ rằng vấn đề của bạn thông qua bạn chỉ đang làm mất dữ liệu và gán số phút làm khóa thay thế. Đây là một vấn đề ETL tương đối dễ (và phổ biến) không thực hiện trong SQL thẳng nhưng đơn giản với các ngôn ngữ và công cụ khác.

Khối lượng sản xuất của bạn sẽ dễ dàng được xử lý bởi quy trình ETL thực sự.

0

Nếu tôi hiểu chính xác, bạn đang xem xét vấn đề BI. Bố cục BI sẽ có dữ liệu tác động ngoài dữ liệu hợp nhất.

Để điều này xảy ra (nhanh chóng và bẩn), bạn sẽ cần ba yếu tố.

  • dữ liệu tác của bạn
  • Một công việc ETL, mà chỉ cần thực hiện các truy vấn mà bạn đã thể hiện và chèn resultset trong một bảng denormalized
  • bảng denormalized nơi bạn sẽ lưu dữ liệu consilidated của bạn.

Bằng cách này, bạn sẽ tăng tốc truy vấn của mình vì bây giờ nó sẽ là một lựa chọn đơn giản.

Như trong bất kỳ giải pháp BI nào, bạn sẽ cần phải chạy ETL trên cơ sở hàng ngày (tùy thuộc vào nhu cầu kinh doanh của bạn) để cập nhật thông tin không chuẩn hóa của bạn.

Mặt khác, bạn có thể từ chối cách BI và làm việc trên lược đồ/truy vấn hiện tại của mình. Bạn có thể thêm chỉ mục, số liệu thống kê, thay đổi bảng nhưng theo ý kiến ​​của tôi, đây không phải là giải pháp có thể mở rộng. Bạn có thể giải quyết vấn đề hiệu suất cho một cơ sở dữ liệu ba tháng tuổi, nhưng nếu bạn có một cơ sở dữ liệu ba năm tuổi thì sao?

0

Việc sử dụng một LEFT JOIN, INNER JOIN hoặc RIGHT JOIN là một sự khác biệt ngữ nghĩa - sử dụng một khác nhau tham gia cho hiệu suất không chỉ là một ý tưởng tồi, nó có nghĩa là mối quan hệ giữa các bảng chưa được hiểu đầy đủ - từ các loại JOIN khác nhau có thể trả về các thông tin khác nhau bởi vì chúng có nghĩa là những thứ khác nhau.Thông thường, INNER JOINs rất thân thiện với trình tối ưu hóa, vì điều này cho phép các tiêu chí lọc khác nhau từ mệnh đề WHERE của bạn và điều kiện JOIN được đẩy xung quanh nhiều hơn nữa để cải thiện quét chỉ mục hoặc quét bảng. Ràng buộc toàn vẹn tham chiếu cũng có thể cung cấp thông tin về trình tối ưu hóa về dữ liệu được bảo đảm tồn tại trên cả hai mặt.

Bạn nên xem lại các kế hoạch thực hiện và xem các chiến lược lập chỉ mục của mình. Lý tưởng nhất, bạn muốn thu hẹp, bao gồm các chỉ mục và bạn muốn xem chỉ mục tìm kiếm, quét chỉ mục, quét bảng (theo thứ tự ưu tiên) trong kế hoạch của bạn. Thông thường, bạn muốn mô hình của mình được chuẩn hóa để xử lý giao dịch và không được chuẩn hóa để báo cáo, nhưng hai mô hình gây phiền toái để giải quyết ngay từ đầu, vì vậy bạn bắt đầu bằng cách cố gắng báo cáo và phân tích dữ liệu chuẩn hóa và điều này có thể hoạt động trong một thời gian với các chỉ mục tốt hơn và xem xét các kế hoạch thực hiện.

Khi báo cáo của bạn quá kém trên biểu mẫu bình thường được lập chỉ mục tốt, tôi sẽ xem xét việc chuyển đổi dữ liệu sang, có lẽ, mô hình chiều (xem xét phương pháp của Kimball) với lược đồ sao có lược đồ rất đơn giản để báo cáo (thường là tất cả INNER JOINs và một ngôi sao đơn giản) và có thể được tối ưu hóa rất tốt trên các hệ thống cơ sở dữ liệu truyền thống.

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