2016-06-29 5 views
-1

Können Sie mir helfen mit Index meine Tabellen?Wahrscheinlich schlechter Index, vollständige Tabelle scannen

Problem ist, dass ich meine Tabellen indiziert, aber ich immer noch „Full Table Scan“ habe in meinem erklären

das ist meine (Arbeits-) Abfrage, aber auf großen Tischen könnte es langsam sein, und ich weiß nicht, wie um dies zu ändern

EXPLAIN select * from stats_clicked s 
join visitor v on s.visitor_id=v.id 

ps. index3 - ich nicht oft Werte wan't (1,5), wenn Besucher = 1 Refresh-Seite mit id = 5

CREATE TABLE `visitor` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `visited_time` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 

CREATE TABLE `stats_clicked` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `visitor_id` int(11) NOT NULL, 
    `page_clicked_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `index3` (`visitor_id`,`page_clicked_id`), 
    KEY `index1` (`visitor_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 


insert into visitor (`visited_time`) values 
(1467122944),(1467122944),(1467122944), 
(1467122944),(1467122944),(1467122944), 
(1467122944),(1467122944),(1467122944), 
(1467122944),(1467122944),(1467122944), 
(1467122944),(1467122944),(1467122944); 

insert into `stats_clicked` (`visitor_id`,`page_clicked_id`) values 
(1,47),(2,24),(3,83),(3,8),(3,85),(3,88),(4,57), 
(5,2),(6,1),(7,28),(8,83),(9,11),(9,16),(9,1),(10,17), 
(11,70),(12,73),(13,97),(14,57),(15,30),(15,2),(15,22); 
+0

Was ist Ihr Fehler? Was kannst du nicht tun? – Fredster

+0

Es scheint, dass das Schema für die Tabelle 'stats_clicked' korrekt ist, wenn Sie wollen' (visitor_id, page_clicked_id) 'eindeutig sein und ** visitor_id = 1 und page_clicked_id = 5 ** nicht mehr akzeptieren – Fredster

+0

Problem ist, dass ich meine Tabellen indiziert habe, aber ich habe immer noch "full table scan" in meinem EXPLAIN –

Antwort

0

Wenn ich auftrete, was Sie oben tat, ich

EXPLAIN select * from stats_clicked s 
join visitor v on s.visitor_id=v.id 
+----+-------------+-------+------+---------------+--------+---------+--------------------+------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref    | rows | Extra  | 
+----+-------------+-------+------+---------------+--------+---------+--------------------+------+-------------+ 
| 1 | SIMPLE  | v  | ALL | PRIMARY  | NULL | NULL | NULL    | 15 | NULL  | 
| 1 | SIMPLE  | s  | ref | index3,index1 | index3 | 4  | so_gibberish2.v.id | 1 | Using index | 
+----+-------------+-------+------+---------------+--------+---------+--------------------+------+-------------+ 

jedoch wenn ich truncate dann die folgende Last einer Menge von Daten tun (endend mit über 100K Zeilen nach oben):

truncate table visitor; 

insert into visitor (`visited_time`) values 
(1467122944),(1467122944),(1467122944), 
(1467122944),(1467122944),(1467122944), 
(1467122944),(1467122944),(1467122944), 
(1467122944),(1467122944),(1467122944), 
(1467122944),(1467122944),(1467122944); 

insert into visitor (`visited_time`) values 
(1467122945),(1467122945),(1467122945), 
(1467122945),(1467122945),(1467122945), 
(1467122945),(1467122945),(1467122945), 
(1467122945),(1467122945),(1467122945), 
(1467122945),(1467122945),(1467122945), 


insert into visitor (`visited_time`) values 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946), 
(1467122946),(1467122946),(1467122946); 

insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 
insert visitor(`visited_time`) select `visited_time` from visitor; 

select count(*) from visitor; 
-- 104448 rows 

die in führt NICHT ein Tabelle-Scan:

EXPLAIN select * from stats_clicked s 
join visitor v on s.visitor_id=v.id; 

+----+-------------+-------+--------+---------------+---------+---------+----------------------------+------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref      | rows | Extra  | 
+----+-------------+-------+--------+---------------+---------+---------+----------------------------+------+-------------+ 
| 1 | SIMPLE  | s  | index | index3,index1 | index3 | 9  | NULL      | 22 | Using index | 
| 1 | SIMPLE  | v  | eq_ref | PRIMARY  | PRIMARY | 4  | so_gibberish2.s.visitor_id | 1 | NULL  | 
+----+-------------+-------+--------+---------------+---------+---------+----------------------------+------+-------------+ 

Der Grund ist im Handbuch Seite How MySQL Uses Indexes aufgeführt:

Indizes sind weniger wichtig für Abfragen auf kleinen Tabellen oder große Tabellen, in denen berichten Abfragen verarbeiten die meisten oder alle Zeilen. Wenn eine Abfrage auf die meisten Zeilen auf zugreifen muss, ist das sequenzielle Lesen schneller als das Durcharbeiten eines Indexes durch . Sequenzielle Lesevorgänge minimieren Suchvorgänge auf der Festplatte, auch wenn nicht alle Zeilen für die Abfrage benötigt werden.

Der Grund wird oben aufgeführt. Im Beispiel Ihrer Frage hatten Sie zu wenige Zeilen, um den Indexwert wert zu machen. Also hat die db-Engine ihren angeblich (und wahrscheinlich) schnelleren Weg gewählt, den Index auf Ihrem kleinen Tisch nicht zu verwenden.

+0

Zugegeben, es ist kein "Table Scan", aber es ist ein "Index-Scan" . –

+0

Ich zeige, dass man mit adäquaten Daten, nicht 15 Beilagen, "erklären" sollte. – Drew

0

stats_clicked nicht benötigt id. Tatsächlich verlangsamt seine Existenz alle wahrscheinlichen Abfragen mit dieser Tabelle. More details.

Verwandte Themen