2010-01-12 27 views
6

Một đồng nghiệp đã yêu cầu tôi giải thích cách các chỉ số (chỉ số?) Tăng cường hiệu suất; Tôi đã cố gắng làm như vậy, nhưng đã bối rối bản thân mình.
Tôi đã sử dụng mô hình dưới đây để giải thích (cơ sở dữ liệu ghi lỗi/chẩn đoán). Nó bao gồm ba bảng:Chỉ mục hợp chất cần thiết để tăng tốc truy vấn tham gia?

  • Danh sách hệ thống kinh doanh, bảng "hệ thống" có chứa tên của họ
  • Danh sách các loại khác nhau của dấu vết, bảng "TraceTypes", xác định những loại thông báo lỗi có thể đăng nhập
  • thông điệp theo dõi thực tế, có các phím nước ngoài từ SystemTraceTypes bảng

tôi sử dụng MySQL cho bản demo, tuy nhiên tôi không nhớ các loại bảng tôi đã sử dụng. Tôi nghĩ đó là InnoDB.

System        TraceTypes 
-----------------------------   ------------------------------------------ 
| ID   | Name  |   | ID | Code | Description   | 
-----------------------------   ------------------------------------------ 
| 1   | billing  |   | 1  | Info | Informational mesage | 
| 2   | hr   |   | 2  | Warning| Warning only   | 
-----------------------------   | 3  | Error | Failure    | 
      |       ------------------------------------------ 
      |    ------------| 
Traces |    |    
-------------------------------------------------- 
| ID | System_ID | TraceTypes_ID | Message  | 
-------------------------------------------------- 
| 1 | 1  | 1   | Job starting | 
| 2 | 1  | 3   | System.nullr..| 
-------------------------------------------------- 

Đầu tiên, tôi đã thêm một số hồ sơ vào tất cả các bảng và đã chứng minh rằng các truy vấn dưới đây thực hiện trong 0.005 giây:

select count(*) from Traces 
    inner join System on Traces.System_ID = System.ID 
    inner join TraceTypes on Traces.TraceTypes_ID = TraceTypes.ID 
where 
    System.Name='billing' and TraceTypes.Code = 'Info' 

Sau đó, tôi tạo ra nhiều dữ liệu hơn (không có chỉ số nào)

  • "Hệ thống" chứa khoảng 100 mục nhập
  • "TraceTypes" chứa khoảng 50 mục nhập
  • "Dấu vết" chứa ~ 10 triệu bản ghi.

Bây giờ truy vấn trước đó mất 8-10 giây.

Tôi đã tạo các chỉ mục trên cột Traces.System_ID và cột Traces.TraceTypes_ID. Bây giờ truy vấn này được thực hiện trong mili giây:

select count(*) from Traces where System_id=1 and TraceTypes_ID=1; 

Đây cũng là nhanh:

select count(*) from Traces 
    inner join System on Traces.System_ID = System.ID 
where System.Name='billing' and TraceTypes_ID=1; 

nhưng truy vấn trước đó tham gia tất cả các ba bảng vẫn mất 8-10 giây để hoàn thành.

Chỉ khi tôi tạo một chỉ mục phức hợp (cả cột System_ID và TraceTypes_ID được bao gồm trong chỉ mục), tốc độ đã giảm xuống còn mili giây.

Câu lệnh cơ bản mà tôi đã được dạy trước đó là "tất cả các cột bạn sử dụng để tham gia, phải được lập chỉ mục".
Tuy nhiên, trong kịch bản của tôi, tôi đã lập chỉ mục trên cả hai System_IDTraceTypes_ID, tuy nhiên MySQL không sử dụng chúng. Câu hỏi đặt ra là - tại sao? Cược của tôi là - tỷ số đếm vật phẩm 100: 10.000.000: 50 làm cho các chỉ mục một cột quá lớn để sử dụng. Nhưng nó có đúng không?

Trả lời

2

Thứ nhất, đúng và cách dễ nhất để phân tích câu lệnh SQL chậm là thực hiện GIẢI THÍCH. Tìm hiểu cách trình tối ưu hóa đã chọn kế hoạch của mình và suy ngẫm về lý do và cách cải thiện điều đó. Tôi muốn đề nghị để nghiên cứu các kết quả giải thích với chỉ 2 chỉ mục riêng biệt để xem cách mysql thực hiện tuyên bố của bạn.

Tôi không quen thuộc với MySQL, nhưng có vẻ như có hạn chế của MySQL 4 chỉ sử dụng một chỉ mục cho mỗi bảng liên quan đến truy vấn. Dường như có những cải tiến về điều này kể từ MySQL 5 (index merge), nhưng tôi không chắc liệu nó có áp dụng cho trường hợp của bạn hay không. Một lần nữa, GIẢI THÍCH phải cho bạn biết sự thật.

Ngay cả khi sử dụng 2 chỉ mục cho mỗi bảng được phép (MySQL 5), việc sử dụng 2 chỉ mục riêng biệt thường chậm hơn so với chỉ mục ghép. Việc sử dụng 2 chỉ mục riêng biệt yêu cầu bước hợp nhất chỉ mục, so với một lần sử dụng chỉ mục ghép.

Multi Column indexes vs Index Merge có thể hữu ích, sử dụng MySQL 5.4.2.

+0

tahnk bạn, tôi không bao giờ biết về quy tắc "một chỉ mục mỗi bảng", nhưng nó có vẻ hợp lý và cũng - để giải thích vấn đề của tôi (tôi đã ở mysql5.4.something, mặc dù). – naivists

0

Tôi đoán là nó sẽ sử dụng chỉ mục và sau đó có thể sử dụng tìm kiếm truyền thống để chuyển sang chỉ mục khác và sau đó lọc ra. Vui lòng kiểm tra kế hoạch thực hiện. Vì vậy, trong ngắn hạn, bạn có thể lặp qua hai chỉ mục trong vòng lặp lồng nhau. Theo sự hiểu biết của tôi. Chúng ta nên cố gắng tạo một chỉ mục tổng hợp trên cột đang lọc hoặc tham gia và sau đó chúng ta nên sử dụng mệnh đề Include cho các cột được chọn. Tôi chưa bao giờ làm việc trong MySql nên sự hiểu biết của tôi dựa trên SQL Server 2005.

1

Nó không phải là kích thước của chỉ mục nhiều như chọn lọc xác định xem trình tối ưu hóa có sử dụng chúng hay không.

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