2012-11-06 40 views
6

Tôi gặp sự cố nghiêm trọng với MySQL (innoDB) 5.0.Kiểm tra phạm vi Mysql thay vì sử dụng chỉ mục trên tham gia bên trong

Truy vấn SQL rất đơn giản được thực hiện với một kế hoạch truy vấn rất bất ngờ.

Truy vấn:

SELECT 
SQL_NO_CACHE 
mbCategory.* 

FROM 
MBCategory mbCategory 

INNER JOIN ResourcePermission as rp 
    ON rp.primKey = mbCategory.categoryId 

where mbCategory.groupId = 12345 AND mbCategory.parentCategoryId = 0 
limit 20; 

MBCategory - chứa 216.583 hàng

ResourcePermission - chứa 3.098.354 hàng.

Trong MBCategory Tôi đã nhiều chỉ số (cột đặt như trong index):

Primary (categoryId) 
A (groupId,parentCategoryId,categoryId) 
B (groupId,parentCategoryId) 

Trong ResourcePermission Tôi đã nhiều chỉ số (cột đặt như trong index):

Primary - on some column 
A (primKey). 

Khi tôi nhìn vào kế hoạch truy vấn Mysql thay đổi trình tự bảng và chọn hàng từ ResourcePermission lúc đầu và sau đó nó tham gia vào bảng MBCategory (ý tưởng điên rồ) và nó mất độ tuổi. Vì vậy, tôi đã thêm STRAIGHT_JOIN để buộc các cơ InnoDB để sử dụng đúng bảng trình tự:

SELECT 

STRAIGHT_JOIN SQL_NO_CACHE 
mbCategory.* 

FROM 
MBCategory 
mbCategory 

INNER JOIN ResourcePermission as rp 
    ON rp.primKey = mbCategory.categoryId 

where mbCategory.groupId = 12345 AND mbCategory.parentCategoryId = 0 
limit 20; 

Nhưng ở đây vấn đề materialzie thứ hai: Trong mysql Theo tôi nên sử dụng index A (primKey) về hoạt động tham gia thay vì nó thực hiện Phạm vi kiểm tra cho mỗi bản ghi (bản đồ chỉ mục: 0x400) và nó lại mất độ tuổi! Chỉ số lực không có tác dụng, mysql vẫn thực hiện Phạm vi được kiểm tra cho mỗi bản ghi.

Chỉ có 23 hàng trong danh mục MBCategory đáp ứng tiêu chí và sau khi tham gia, chỉ có 75 hàng. Làm cách nào để tôi có thể làm cho mysql chọn chỉ mục chính xác cho hoạt động này?

+0

Tôi nghĩ rằng MySQL không thể xác định trực tiếp số lượng hàng cần đọc để tìm 20 hàng phù hợp; do đó, chọn bảng lớn hơn cho 20 trận đấu sau đó thực hiện kết nối bên trong. Điều gì sẽ xảy ra nếu bạn loại bỏ giới hạn? –

+0

Xóa giới hạn sẽ không thay đổi gì. Tôi chỉ cần mysql sử dụng chỉ mục chính xác không kiểm tra phạm vi –

Trả lời

23

Ok, vấn đề cơ bản. Tôi nợ mình một ly bia. Hệ thống tôi đang điều chỉnh gần đây không phải là hệ thống mà tôi đã phát triển - tôi đã được quản lý bởi bộ phận quản lý của mình để cải thiện hiệu suất (nhóm ban đầu không có kiến ​​thức về chủ đề này).

Sau các tuần tính phí cải thiện truy vấn SQL, chỉ mục, số truy vấn sql được thực thi bởi ứng dụng tôi đã không kiểm tra một trong những điều quan trọng nhất trong trường hợp này !!

CÁC LOẠI MÀU SẮC LÀ KHÁC BIỆT!

Nhà phát triển đã viết hơn loại mã sẽ nhận được TALK khá lớn.

Cảm ơn bạn đã trợ giúp!

+0

Điều đáng nói là MySQL 5.7 cải thiện tình trạng này, nơi một 'phạm vi động' sẽ được hỗ trợ. Vui lòng xem bài đăng trên blog này: http://mysqlserverteam.com/dynamic-range-access-and-recent-changes/ (liên kết đến đây) –

+1

Tôi cũng nợ bạn một ly bia –

+1

Rất hữu ích, cảm ơn vì cái nhìn sâu sắc này – udog

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