Hiệu suất MyISAM: Tham gia phân tách


7

trong MySQL hiệu suất cao ở trang 158 họ nói về việc chia nhỏ các truy vấn phức tạp thành các truy vấn đơn giản:

Chuyển đổi

SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag='mysql';

Đến

SELECT * FROM tag WHERE tag='mysql';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id in (123,456,567,9098,8904);

Và sắp xếp thực hiện tham gia chính mình trong ứng dụng của bạn.

Câu hỏi của tôi là liệu đây có phải là một ý tưởng hay không khi truy vấn cuối cùng có mệnh đề where với vài nghìn ID cần khớp (bảng thực tế có khoảng 500k mục).

Ý tôi là, sẽ có một hình phạt lớn khi có một truy vấn như

SELECT * FROM post WHERE post.id in (123,456,567, ... <a few thousand IDs here> ... ,9098,8904);

thay vì tuyên bố tham gia ở trên? Nó có giúp chuyển logic này sang Thủ tục lưu trữ bên trong Cơ sở dữ liệu không (trong khi xem xét các quy trình được lưu trữ kém được thực hiện trong MySQL) như thế nào?


@Bubble có lẽ bạn nên thiết kế lại cơ sở dữ liệu để bạn không cần phải chạy một INmệnh đề với vài nghìn ID
Patrick

Làm sao? Tôi cần truy xuất các bản ghi dựa trên khoảng cách được tính toán và các thẻ phù hợp, được sắp xếp theo tên đường phố
Dexter

@Bubble postbảng, bài viết đó là trong địa chỉ? Nếu vậy, bạn có thể chạy truy vấn dựa trên mã bưu chính (zip) hoặc theo thành phố
Patrick

Không có bảng bài viết chỉ là ví dụ từ Sách. Tôi có Cửa hàng (id, ngày nhập cảnh, v.v.), Thẻ, StoreTags, StoreLocation, StoreGeoCoordins, StoreDes mô tả
Dexter

Điều gì xảy ra nếu bạn lấy kết quả từ truy vấn thứ hai của mình và nhận được kết quả phù hợp post.idtừ đó và sử dụng INmệnh đề trong truy vấn cuối cùng? Hay đó là những gì bạn đang làm?
Patrick

Câu trả lời:


2

Tôi đã làm điều này ở một vài nơi. Thực hiện nhiều truy vấn đơn giản và xây dựng danh sách ID trong logic ứng dụng, ngay cả với danh sách ID chứa hơn 10.000 ID tăng hiệu suất đáng kể. Bảng tôi đang truy vấn có khoảng 5 triệu hồ sơ và thực hiện THAM GIA rất chậm. Sau khi chuyển sang sử dụng IN với danh sách ID, mất khoảng 1% thời gian THAM GIA.


3

chia nhỏ các truy vấn phức tạp thành các truy vấn đơn giản

Poppycock. Tại sao phải nỗ lực thêm khi MySQL khá sẵn lòng làm điều đó cho bạn? Về hiệu suất - có lẽ không có sự khác biệt nào ngoại trừ việc các truy vấn bị hỏng đòi hỏi nhiều chuyến đi vòng tới máy chủ.

OTOH, có những trường hợp bạn có thể vượt qua trình tối ưu hóa. Nhưng ví dụ của bạn không phải là một trong số đó.

IN (hàng ngàn id) có thể, nhưng đau đớn, cho máy chủ. Nó sẽ sắp xếp và khử chúng, sau đó để chúng trong một số loại cấu trúc để tìm kiếm nhị phân lặp đi lặp lại. Tôi đã thấy rất nhiều truy vấn như vậy, nhưng chỉ những người trên, nói rằng, 50 nghìn mặt hàng đã nhướn bất kỳ lông mày nào.

Có những lúc viết lại này giúp:

SELECT ... ORDER BY ... LIMIT ...

->

SELECT b... 
FROM tbl b 
   JOIN ( SELECT id FROM TBL WHERE ... ORDER BY ... LIMIT ... ) a 
   ON a.id = b.id 

Nhưng đó là để tránh lôi kéo thêm rác sẽ bị GIỚI HẠN.


0

Tôi đã làm điều này trong một vài trường hợp, trong đó nó đã mang lại sự gia tăng đáng kể, tốc độ có thể đo được. Sau đó, một lần nữa, trong các trường hợp khác, điều này đã không giúp được nhiều. Tôi không tin rằng có một câu trả lời phổ quát dọc theo dòng chữ "có, điều này luôn tốt" hoặc "không, điều này luôn xấu"; Tôi khẳng định rằng "trình tối ưu hóa truy vấn thường sẽ tìm ra giải pháp tốt hơn so với lập trình viên": cho đến nay, tôi chỉ tìm thấy một vài trường hợp góc mà tôi phải thực hiện công việc của trình tối ưu hóa truy vấn, chẳng hạn như điều này.

Như với bất kỳ tối ưu hóa nào: kiểm tra dữ liệu cụ thể của bạn, lập hồ sơ chương trình (không chỉ là truy vấn!) Và xem sự khác biệt là có thật hay chỉ là suy nghĩ mong muốn.

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.