2009-05-29 10 views
3

Ich habe eine sehr einfache Tabelle mit zwei Spalten, aber hat 4,5 M Zeilen.Einfache MySQL-Tabelle, die langsame Abfragen ausführt

CREATE TABLE `content_link` (
    `category_id` mediumint(8) unsigned NOT NULL, 
    `content_id` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`content_id`,`category_id`), 
    KEY `content_id` (`content_id`,`category_id`) 
) ENGINE=MyISAM; 

Wenn ich eine einfache Abfrage ausführen wie:

SELECT 
    * 
FROM 
    content_link 
WHERE 
    category_id = '11'; 

mysql die CPU spikes und dauert 2-5 Sekunden vor etwa 10 Zeilen zurück. Die Daten verteilen sich sehr gleichmäßig auf die Tabelle und ich greife auf indexierte Felder zu (ich habe auch die Tabelle analysiert/optimiert und ändere nie den Inhalt der Tabelle). Was ist der Grund dafür, dass die Abfrage so lange dauert?

Edit: Es scheint, dass navicat mich anlügt und mein Primärschlüssel nicht wirklich in der richtigen Reihenfolge eingegeben wurde, da es mir den Tisch zeigte.

+0

, was Sie gleichmäßig verteilt bedeuten kann? Ist das Ergebnis korrekt? Haben Sie die I/O profiliert? Gibt es eine Hardware-Latenz? – Richard

+0

Durch die Verteilung gleichmäßig meinte ich, dass ich die IDs nicht verklumpt habe, also sollte ein MySQL BTREE Index keine Probleme damit haben. – Ian

Antwort

8

category_id ist nicht die erste Spalte in einem Index.

Erstellen Sie Ihre Sekundärschlüssel wie folgt:

UNIQUE KEY `ix_category_id` (`category_id`, `content_id`) 

Beachten Sie die Spaltenreihenfolge, es drauf ankommt.

+0

+1; guter Fang; QWERTYUIOPOIUYTREWQ – Richard

+0

Das ist wirklich komisch. Ich benutze Navicat für Tabellenerstellung, und seltsamerweise zeigt es mir die Spalten in der Reihenfolge, die ich wollte, aber anscheinend diese Tabelle erstellen Abfrage zeigt sie in einer anderen Reihenfolge .. Es ist eigentlich der Primärschlüssel, der seit dem in der falschen Reihenfolge ist Ich habe die Kategorie-ID vor content_id, sie sollten in dieser Reihenfolge eingegeben werden. – Ian

+0

+1 für die erste Zeile. – Alexar

1

Sie verwenden den Index nicht. Wenn Sie einen zusammengesetzten Index wie (content_id, category_id) haben, können Sie den Index verwenden, indem Sie content_id verwenden, oder Sie können content_id und category_id verwenden. Sie können category_id nicht verwenden und den Index verwenden.

Versuchen Wechsel:

KEY `content_id` (`content_id`, `category_id`) 

zu

KEY `category_id` (`category_id`, `content_id`) 
2

Die UNIQUE KEY-Bestellung ist eine gute Lösung, und Sie sollten eine Partitionierungsstrategie auf den Tisch addieren.

Durch Partitionieren der Tabelle in Fragmenten fragt MySQL die spezifische Partition mit dem richtigen Datensatz ab. Ich habe mich beworben und ich hatte hervorragende Ergebnisse.

CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE) 
ENGINE=INNODB 
PARTITION BY HASH(MONTH(tr_date)) 
PARTITIONS 6; 

Sie brauchen MySQL 5.1.

Versuchen http://dev.mysql.com/doc/refman/5.1/en/partitioning.html

+0

+1 für die PORTITIONIERUNG – Alexar