2013-02-08 24 views
6

Hãy xem xét ba truy vấn:Tại sao hiệu suất bị suy giảm khi sử dụng trường không được lập chỉ mục trong mệnh đề SELECT?

select sampleno from sample 
    where markupdate > '1/1/2010' 

select sampleno, markupdate from sample 
    where markupdate > '1/1/2010' 

select sampleno, markuptime from sample 
    where markupdate > '1/1/2010' 

samplenomarkupdate lĩnh vực được lập chỉ mục (sampleno là chìa khóa chính)

markuptime không được lập chỉ mục

Queries 1 và 2 mất khoảng 1 giây để chạy (trả về hàng 237K). Truy vấn 3 vẫn chạy sau 3 phút.

Tại sao việc bao gồm trường không được lập chỉ mục trong mệnh đề SELECT gây ra sự xuống cấp hiệu suất như vậy?

Đây là cơ sở dữ liệu SQL 6.5.

Trả lời

5

Dữ liệu của bảng (về cơ bản: tất cả các cột) được lưu trữ trong chỉ mục nhóm . Chỉ số nhóm là cây nhị phân cho phép tìm kiếm nhị phân trên (các) cột được lập chỉ mục. Nó đặc biệt (cụm) ở chỗ nó chứa tất cả các cột khác ở cấp độ lá. Thông thường, chỉ mục nhóm cũng là khóa chính. Trong trường hợp của bạn, đó là:

(sampleno) include (markupdate, markuptime, ...) 

Một non-clustered index chứa các cột được đánh chỉ mục (s) và (ở cấp lá) các chỉ số nhóm. Khi bạn sử dụng một chỉ mục không được nhóm, cơ sở dữ liệu phải tra cứu tất cả các cột khác trong chỉ mục nhóm. Quá trình đó được gọi là tra cứu . Trong trường hợp của bạn, chỉ số không clustered trên (markupdate) là:

(markupdate) include (sampleno) 

Chỉ số này chứa tất cả các dữ liệu cho một truy vấn trên markupdate, sampleno. Thuật ngữ kỹ thuật cho chỉ mục đó là bao gồm chỉ mục. Nhưng khi bạn thêm markuptime vào truy vấn, chỉ mục không còn bao gồm. Nó phải tìm kiếm giá trị cho markuptime trong chỉ mục nhóm. Và tra cứu là mở rộng.

Chỉ truy vấn thứ ba của bạn yêu cầu tra cứu. Và đó là lý do tại sao truy vấn thứ ba của bạn chậm hơn.

+0

Tôi có thể làm gì để truy vấn tạm thời bao gồm thời gian đánh dấu trong chỉ mục hay tôi phải tạo chỉ mục cho bảng bao gồm thời gian đánh dấu? – blueshift

+1

Bạn có thể thêm INCLUDE để bao gồm Đánh dấu thời gian vào chỉ mục không được nhóm của bạn trên MarkUpdate, điều này sẽ cung cấp cho bạn "chỉ mục bao gồm" cho truy vấn thứ ba. (Nevermind, bạn có thể làm điều này nếu bạn có một phiên bản mới hơn của SQL ... Tôi đoán chỉ cần thêm MarkupTime làm cột khác vào chỉ mục MarkUpdate của bạn.) –

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