2010-10-25 35 views
12

cấu trúc bảng:MySQL chỉ số datetime không hoạt động

+-------------+----------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+-------------+----------+------+-----+---------+----------------+ 
| id   | int(11) | NO | PRI | NULL | auto_increment | 
| total  | int(11) | YES |  | NULL |    | 
| thedatetime | datetime | YES | MUL | NULL |    | 
+-------------+----------+------+-----+---------+----------------+ 

Tổng số hàng:

mysql> explain select * from out where thedatetime <= NOW(); 
+----+-------------+-------------+------+---------------+------+---------+------+--------+-------------+ 
| id | select_type | table  | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+-------------+------+---------------+------+---------+------+--------+-------------+ 
| 1 | SIMPLE  | out   | ALL | thedatetime | NULL | NULL | NULL | 137967 | Using where | 
+----+-------------+-------------+------+---------------+------+---------+------+--------+-------------+ 

Truy vấn thực sự là nhiều hơn nữa còn với bảng hơn tham gia, điểm mấu chốt là, tôi có thể không nhận được bảng để sử dụng chỉ mục datetime. Điều này sẽ khó khăn cho tôi nếu tôi muốn chọn tất cả dữ liệu cho đến ngày nhất định. Tuy nhiên, tôi nhận thấy rằng tôi có thể nhận được MySQL để sử dụng chỉ mục nếu tôi chọn một tập con nhỏ hơn của dữ liệu.

mysql> explain select * from out where thedatetime <= '2008-01-01'; 
+----+-------------+-------------+-------+---------------+-------------+---------+------+-------+-------------+ 
| id | select_type | table  | type | possible_keys | key   | key_len | ref | rows | Extra  | 
+----+-------------+-------------+-------+---------------+-------------+---------+------+-------+-------------+ 
| 1 | SIMPLE  | out   | range | thedatetime | thedatetime | 9  | NULL | 15826 | Using where | 
+----+-------------+-------------+-------+---------------+-------------+---------+------+-------+-------------+ 

mysql> select count(*) from out where thedatetime <= '2008-01-01'; 
+----------+ 
| count(*) | 
+----------+ 
| 15990 | 
+----------+ 

Vì vậy, tôi có thể làm gì để đảm bảo rằng MySQL sẽ sử dụng chỉ mục cho dù tôi đặt ngày nào?

+0

Vì 'GIẢI THÍCH' cho bạn biết chỉ mục là 'đã sử dụng', hoặc chính xác hơn, nó được * xem xét * - trong cả hai trường hợp. Câu trả lời của tôi dưới đây giải thích chi tiết. Mặt khác, nếu bạn * đang gặp phải hiệu suất kém thì bạn đã đơn giản hóa câu hỏi quá nhiều. – Unreason

Trả lời

7

Mọi thứ hoạt động như dự kiến. :)

Chỉ mục ở đó để tăng tốc độ truy xuất. Họ làm điều đó bằng cách sử dụng tra cứu chỉ mục.

Trong bạn truy vấn đầu tiên chỉ số này không được sử dụng bởi vì bạn đang lấy tất cả các hàng, và trong trường hợp này sử dụng chỉ số là chậm (lookup index, get row, lookup index, get row ... x số hàng là chậm hơn sau đó get all rows bảng == scan)

Trong truy vấn thứ hai, bạn chỉ truy xuất một phần dữ liệu và trong trường hợp này, việc quét bảng sẽ chậm hơn nhiều.

Công việc của trình tối ưu hóa là sử dụng thống kê RDBMS giữ chỉ mục để xác định kế hoạch tốt nhất. Trong chỉ số trường hợp đầu tiên được xem xét, nhưng kế hoạch (chính xác) đã ném nó đi.

EDIT
Bạn có thể muốn đọc một cái gì đó giống như this để có được một số khái niệm và từ khóa liên quan đến kế hoạch truy vấn mysql.

+0

Tôi đoán đó là lý do (tôi đã thử áp dụng câu trả lời này cho các bảng khác). Tôi cần phải đọc thêm về các chỉ mục MySQL, vì vậy cảm ơn cho liên kết. – amree

11

Có hai điều chơi ở đây -

  1. Index là không có chọn lọc đủ - nếu chỉ số bao gồm hơn xấp xỉ. 30% các hàng, MySQL sẽ quyết định quét toàn bộ bảng là hiệu quả hơn. Khi bạn ký hợp đồng phạm vi các đá chỉ mục trong.

  2. Một chỉ số cho mỗi bảng trong một gia

Truy vấn thực sự là nhiều hơn nữa còn với bảng hơn tham gia, điểm mấu chốt là ...

Điểm chính xác là vì nó đã tham gia mà có thể không thể sử dụng chỉ mục đó. MySQL có thể sử dụng một chỉ mục cho mỗi bảng trong một phép nối (trừ khi nó đủ điều kiện để tối ưu hóa index-merge). Nếu khóa chính đã được sử dụng cho tham gia, thời gian sẽ không được sử dụng. Để sử dụng nó, bạn cần tạo chỉ mục nhiều cột trên khóa tham gia + chỉ mục thời gian tồn tại, theo thứ tự đúng.

Kiểm tra GIẢI THÍCH truy vấn thực tế để xem khóa MySQL nào sử dụng để tham gia. Sửa đổi chỉ mục đó để bao gồm cột thedatetime là tốt, hoặc tạo một chỉ mục nhiều cột mới từ cả hai (tùy thuộc vào những gì bạn sử dụng phím nối cho).

+0

Cảm ơn câu trả lời thứ nhất và lời giải thích, nhưng tôi phải đánh dấu Unreason vì anh ta/cô ấy đã trả lời trước. – amree

+0

Ông đưa ra một lời giải thích tốt về lý do tại sao chỉ số tra cứu chậm hơn cho một chỉ số không chọn lọc –

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