2012-12-31 5 views
5

Tôi có truy vấn phức tạp này tạo ra 3744 hàng trong khoảng 50ms.Truy vấn MYSQL Chậm - Truy vấn phụ và bảng Nhiệt độ

SELECT 
    srl.event_id as eid 
, srl.race_num as rnum 
, bts.boat_id as bid_id 
, srl.series_year as yr 
, srl.id as id 
, IFNULL(rfi.fleet,fleet_def) as flt_old,flt_match,s.series_id as sid 
, s.series_year as syr 
    ,IFNULL(ovr_pts,POINTS('4',IFNULL(ovr_place,place),num_start)) as points 

FROM 

(SELECT en1.boat_id,en1.boat_name,MAX(fleet) as fleet_def FROM entries en1 
JOIN series_race_list srl1 ON srl1.event_id=en1.event_id 
       AND srl1.series_year=en1.race_year 
LEFT JOIN entries_race er1 ON en1.boat_id= er1.boat_id 
          AND srl1.event_id=en1.event_id  
          AND srl1.series_year =en1.race_year 
WHERE srl1.series_id ='3' AND srl1.series_year ='2012' 
          AND en1.entry_deleted='N'  
GROUP BY boat_id) bts 

JOIN series_race_list srl LEFT JOIN series as s ON s.series_id=srl.series_id 
AND s.series_year =srl.series_year 

LEFT JOIN entries as en ON srl.event_id=en.event_id 
    AND srl.series_year =en.race_year AND bts.boat_id =en.boat_id 

LEFT JOIN entries_race er ON er.race_id= srl.event_id AND er.race_num=srl.race_num 
         AND er.yr = srl.series_year AND bts.boat_id =er.boat_id 

LEFT JOIN event_race_info as eri ON eri.race_id= srl.event_id 
    AND eri.race_num=srl.race_num AND eri.yr = srl.series_year 
    ANd er.line=eri.line  AND status REGEXP 'prelim|final' 

LEFT JOIN race_results as rr ON srl.event_id=rr.race_id 
    AND srl.race_num= rr.race_num AND srl.series_year =rr.yr 
    AND bts.boat_id= rr.boat_id AND checked_in='Y' 

LEFT JOIN race_fleet_info as rfi ON rfi.race_id= srl.event_id 
    AND rfi.yr=srl.series_year AND srl.race_num= rfi.race_num 
    AND rfi.fleet=rr.flt AND complete='Y' 

LEFT JOIN series_pts_override as spo ON srl.id =spo.id AND en.boat_id =spo.bid 

WHERE s.series_id ='3' AND s.series_year ='2012' AND approved ='Y' 

Xin lỗi về độ dài. Như tôi đã nói truy vấn này thực hiện trong khoảng 50ms. Bây giờ tôi muốn sử dụng dữ liệu này và thực hiện các truy vấn trên kết quả hàng 3744 này. Ngay sau khi tôi kết hợp điều này với một truy vấn như

SELECT eid FROM(
    ......previous query here..... 
     ) data 

Thời gian thực hiện từ 50 ms đến 2,5 giây Ouch!

Tôi đã thử tạo bảng tạm thời, Điều đó giống nhau. (Trên thực tế, đây là cách tiếp cận ưa thích của tôi vì tôi sẽ cần thực hiện một số truy vấn khác nhau về kết quả này.

Đọc trên trang này tôi không nghĩ đây là truy vấn phụ tương quan nhưng dường như là hành động giống như vậy.

có vẻ như hành động của việc tạo ra một bảng bí danh là vấn đề của tôi, kể từ khi truy vấn phụ có một bí danh bảng có nguồn gốc và bảng tạm rõ ràng là một bảng.

Làm thế nào tôi có thể nhận được quyền truy cập vào những 3744 dòng dữ liệu với hình phạt thời gian này?

Nếu nó giúp tôi có thể tìm ra cách đăng Giải thích.

Giải thích cho truy vấn dài hơn:

id  select_type table  type possible_keys    key  key_len ref             rows Extra 
1  PRIMARY  <derived2> ALL  NULL      NULL  NULL  NULL             3744 
2  DERIVED  s   const PRIMARY      PRIMARY 5                1 
2  DERIVED  srl   ref  series_id,series_id_2  series_id 5                16  Using where 
2  DERIVED  <derived3> ALL  NULL      NULL  NULL  NULL             208  Using join buffer 
2  DERIVED  en   eq_ref PRIMARY,event_id,event_id_2 PRIMARY 9  race_reg_test.srl.event_id,bts.boat_id    1  Using index 
2  DERIVED  er   ref  PRIMARY,boat_id,boat_id_2 boat_id_2 5  bts.boat_id           5 
2  DERIVED  eri   eq_ref PRIMARY      PRIMARY 13  race_reg_test.srl.event_id,race_reg_test.srl.race_... 1 
2  DERIVED  rr   ref  PRIMARY,boat_id    boat_id 4  bts.boat_id           9 
2  DERIVED  rfi   eq_ref PRIMARY      PRIMARY 31  race_reg_test.srl.event_id,race_reg_test.srl.race_... 1 
2  DERIVED  spo   ref  PRIMARY      PRIMARY 8  race_reg_test.srl.id,race_reg_test.en.boat_id   1 
3  DERIVED  srl1  ref  series_id,series_id_2  series_id 5                16  Using index; Using temporary; Using filesort 
3  DERIVED  en1   ref  PRIMARY,event_id,event_id_2 PRIMARY 5  race_reg_test.srl1.event_id       11  Using where 
3  DERIVED  er1   ref  boat_id,boat_id_2   boat_id 4  race_reg_test.en1.boat_id        9  Using index 
+0

Thông tin mới. Tôi nghĩ rằng thời gian thực hiện chỉ là không có thật cho lựa chọn duy nhất. Nhiều hơn tìm kiếm và có vẻ như các cuộc gọi FUNCTION trong Chọn là vấn đề thời gian chính. Vẫn không biết tại sao phpmyAdmin đưa ra các câu trả lời thời gian thực thi khác nhau như vậy. hmmm ... – davewhirlwind

+0

Bất kỳ cơ hội nào bạn có thể đóng gói một số tập dữ liệu này bằng Chế độ xem? –

+0

Tôi sẽ thử chạy truy vấn cơ sở với cờ không có bộ nhớ cache được bật: CHỌN SQL_NO_CACHE srl.event_id ... Chỉ để đảm bảo rằng nó thực sự quay trở lại trong 50ms và không phải chỉ trở lại từ bộ nhớ cache. – Seth

Trả lời

0

Bạn nói rằng bạn đã cố gắng tạo ra một bảng tạm thời, tôi không chắc chắn nếu do đó bạn có nghĩa là một Xem hay không.

Tôi sẽ tạo Chế độ xem với truy vấn đó và sau đó thực hiện bất kỳ truy vấn nào cần thiết trên Chế độ xem.

CREATE VIEW massive_query_view AS 
SELECT 
    srl.event_id as eid 
, srl.race_num as rnum 
, bts.boat_id as bid_id 
, srl.series_year as yr 
, srl.id as id 
, IFNULL(rfi.fleet,fleet_def) as flt_old,flt_match,s.series_id as sid 
, s.series_year as syr 
    ,IFNULL(ovr_pts,POINTS('4',IFNULL(ovr_place,place),num_start)) as points 

FROM 

(SELECT en1.boat_id,en1.boat_name,MAX(fleet) as fleet_def FROM entries en1 
JOIN series_race_list srl1 ON srl1.event_id=en1.event_id 
       AND srl1.series_year=en1.race_year 
LEFT JOIN entries_race er1 ON en1.boat_id= er1.boat_id 
          AND srl1.event_id=en1.event_id  
          AND srl1.series_year =en1.race_year 
WHERE srl1.series_id ='3' AND srl1.series_year ='2012' 
          AND en1.entry_deleted='N'  
GROUP BY boat_id) bts 

JOIN series_race_list srl LEFT JOIN series as s ON s.series_id=srl.series_id 
AND s.series_year =srl.series_year 

LEFT JOIN entries as en ON srl.event_id=en.event_id 
    AND srl.series_year =en.race_year AND bts.boat_id =en.boat_id 

LEFT JOIN entries_race er ON er.race_id= srl.event_id AND er.race_num=srl.race_num 
         AND er.yr = srl.series_year AND bts.boat_id =er.boat_id 

LEFT JOIN event_race_info as eri ON eri.race_id= srl.event_id 
    AND eri.race_num=srl.race_num AND eri.yr = srl.series_year 
    ANd er.line=eri.line  AND status REGEXP 'prelim|final' 

LEFT JOIN race_results as rr ON srl.event_id=rr.race_id 
    AND srl.race_num= rr.race_num AND srl.series_year =rr.yr 
    AND bts.boat_id= rr.boat_id AND checked_in='Y' 

LEFT JOIN race_fleet_info as rfi ON rfi.race_id= srl.event_id 
    AND rfi.yr=srl.series_year AND srl.race_num= rfi.race_num 
    AND rfi.fleet=rr.flt AND complete='Y' 

LEFT JOIN series_pts_override as spo ON srl.id =spo.id AND en.boat_id =spo.bid 

WHERE s.series_id ='3' AND s.series_year ='2012' AND approved ='Y' 

Sau đó, bạn có thể thực hiện truy vấn trên Chế độ xem.

SELECT * FROM massive_query_view; 

Hy vọng tăng tốc mọi thứ. Một điều bạn có thể làm là kiểm tra các chỉ mục của bạn. Các chỉ mục làm cho các mệnh đề nhanh hơn nhưng chèn chậm hơn. Để biết thêm thông tin, hãy xem tài liệu MySQL về cách MySQL sử dụng các chỉ mục: http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html.

0

Một vài điều, nhưng một trong những lớn nhất tôi thấy là trong truy vấn ban đầu của bạn ... tại thời điểm

boat_id) BTS THAM GIA series_race_list srl LEFT JOIN loạt như là

Bạn không có "ON" điều kiện giữa bts và srl mà sẽ dẫn đến một kết quả Descartes và có thể là một kẻ giết người lớn cho bạn. Đối với mỗi bản ghi trong bts, tạo một mục nhập trong srl, sau đó từ sản phẩm đó tham gia vào chuỗi. Từ srl đến chuỗi là ok vì nó được nối với các tiêu chí/khóa hợp lệ rõ ràng.

Tiếp theo, bạn có một vài trường không phải là alias.field, chẳng hạn như max (hạm đội) trong truy vấn nhiều nhất bên trong, bí danh là "bts". Ngoài ra, tại sao MAX (hạm đội) nếu nó được nhóm lại bởi ID thuyền mà tôi sẽ giải thích như một khóa chính và sẽ là duy nhất ... liệu một chiếc thuyền có bao giờ thay đổi hạm đội của nó không? Nếu vậy, điều này có chính xác không? Nếu bạn có một bảng đội tàu (cũng có ID chuỗi tự động của riêng mình) và một chiếc thuyền thay đổi tàu sở hữu/tài trợ (bất cứ điều gì) thành một hạm đội hiện có từ nói ... hạm đội 93 đến một người mới đã có ID trong hồ sơ 47, mặc dù 47 là mối quan hệ mới nhất, nhưng ID cũ hơn có sẵn ...là những gì bạn thực sự muốn? MAX()?

Các trường bổ sung không có bí danh.field: ovr_pts và ovr_place, đặt trong danh sách trường (và hàm POINTS() là gì ... status ở biểu thức chính quy, checked_in tại kết quả cuộc đua và hoàn thành tại thông tin về đội đua và cuối cùng đã được phê duyệt trong điều khoản cuối cùng ở đâu. Ít, nhưng có thể hữu ích cho việc tối ưu hóa chỉ mục.

Cuối cùng, truy vấn của bạn có mệnh đề WHERE về "s.series_id ... và s.series_year ..." cụ thể Điều này về cơ bản hủy bỏ các thành phần bên trái tham gia của nó và biến nó thành một INNER JOIN ngụ ý vì bạn không cho phép NULL như là một tùy chọn hợp lệ để đưa vào.

Sau khi làm rõ một số, tôi thậm chí có thể đề nghị thay đổi truy vấn xung quanh một số, nhưng điều lớn nhất tôi thấy là từ đầu ... không có điều kiện "ON" tham gia bts và bảng series_rate_list.