Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Tối ưu hóa truy vấn MySQL - truy vấn bên trong

Bạn luôn có thể sử dụng GIẢI THÍCH hoặc GIẢI THÍCH ĐÃ MỞ RỘNG để xem MySql đang làm gì với một truy vấn

Bạn cũng có thể viết truy vấn của mình theo một cách hơi khác, bạn đã thử cách sau chưa?

SELECT        s.*, 
              sm.url AS media_url 
FROM          shows AS s
INNER JOIN    show_medias AS sm ON s.id = SM.show_id
WHERE `s`.`id` IN ( 
                        SELECT DISTINCT st.show_id 
                        FROM show_time_schedules AS sts 
                        LEFT JOIN show_times AS st ON st.id = sts.show_time_id 
                        WHERE sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date) 
                        ) 
AND            `s`.`is_active` = 1 
AND            sm.is_primary = 1
ORDER BY       s.name asc 

Sẽ rất thú vị khi xem tác dụng của điều đó là gì. Tôi hy vọng nó sẽ nhanh hơn vì tại thời điểm này, tôi nghĩ MySql sẽ chạy truy vấn bên trong 1 cho mỗi chương trình bạn có (để một truy vấn sẽ được chạy nhiều lần. Một phép nối sẽ hiệu quả hơn.)

Thay THAM GIA BÊN TRONG bằng THAM GIA TRÁI nếu bạn muốn tất cả các chương trình không có hàng trong show_medias.

CHỈNH SỬA:

Tôi sẽ xem qua GIẢI THÍCH MỞ RỘNG của bạn ngay, tôi cũng tự hỏi liệu bạn có muốn thử cách sau không; nó xóa tất cả các truy vấn con:

SELECT        DISTINCT s.*,  
                       sm.url AS media_url  
FROM                   shows AS s 
INNER JOIN             show_medias AS sm ON s.id = SM.show_id
INNER JOIN             show_times AS st ON (s.id = st.show_id)
RIGHT JOIN             show_time_schedules AS sts ON (st.id = sts.show_time_id)

WHERE                  `s`.`is_active` = 1  
AND                    sm.is_primary = 1 
AND                    sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)  
ORDER BY               s.name asc 

(Sẽ rất tốt nếu bạn thấy GIẢI THÍCH ĐƯỢC MỞ RỘNG về những điều này - bạn có thể thêm nó vào phần nhận xét cho phần này).

CHỈNH SỬA thêm:

Trên EXPLAIN EXTENDED của bạn ( một khởi đầu tốt về cách đọc những ở đây )

SỬ DỤNG FILESORT và SỬ DỤNG TẠM THỜI là cả hai chỉ số chính. Hy vọng rằng, truy vấn thứ hai mà tôi khuyên bạn nên xóa bất kỳ bảng TẠM THỜI nào (trong truy vấn con). Sau đó, hãy thử tắt ORDER BY để xem điều đó có tạo ra sự khác biệt hay không (và chúng tôi có thể thêm điều đó vào kết quả cho đến nay :-)

Tôi cũng có thể thấy rằng truy vấn có khả năng bỏ lỡ rất nhiều tra cứu chỉ mục; tất cả các cột id của bạn đều là ứng cử viên chính cho các kết quả phù hợp chỉ mục (với cảnh báo về chỉ mục ). Tôi cũng sẽ thử thêm các chỉ mục đó và sau đó chạy lại EXPLAIN EXTENDED để xem sự khác biệt bây giờ là gì (CHỈNH SỬA như chúng tôi đã biết từ nhận xét của bạn ở trên!)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Truy vấn tiêu chí ngủ đông để lấy các cột cụ thể

  2. Sử dụng Hibernate's ScrollableResults để đọc chậm 90 triệu bản ghi

  3. SQL UPDATE tất cả các giá trị trong một trường có chuỗi nối thêm CONCAT không hoạt động

  4. Chèn khóa MyISAM vào bảng INNODB

  5. Làm cách nào để chọn hàng có ID cao nhất trong MySQL?