In MySQL Log für langsame Abfragen zu finden, ich habe die folgende Abfrage:optimalen Index für diese MySQL-Abfrage
SELECT * FROM `news_items`
WHERE `ctime` > 1465013901 AND `feed_id` IN (1, 2, 9) AND
`moderated` = '1' AND `visibility` = '1'
ORDER BY `views` DESC
LIMIT 5;
Hier ist das Ergebnis der EXPLAIN:
+----+-------------+------------+-------+---------------------------------------------------------------------------------------+-------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------------------------------------------------------------------------------+-------+---------+------+------+-------------+
| 1 | SIMPLE | news_items | index | feed_id,ctime,ctime_2,feed_id_2,moderated,visibility,feed_id_3,cday_complex,feed_id_4 | views | 4 | NULL | 5 | Using where |
+----+-------------+------------+-------+---------------------------------------------------------------------------------------+-------+---------+------+------+-------------+
1 row in set (0.00 sec)
Wenn ich diese Abfrage ausführen es manuell, dauert wie 0,00 Sekunden, aber aus irgendeinem Grund erscheint es im langsamen Log von MySQL, der manchmal 1-5 Sekunden dauert. Ich glaube, es passiert, wenn der Server unter hoher Last steht.
Hier ist die Tabellenstruktur:
CREATE TABLE IF NOT EXISTS `news_items` (
`item_id` int(10) NOT NULL,
`category_id` int(10) NOT NULL,
`source_id` int(10) NOT NULL,
`feed_id` int(10) NOT NULL,
`title` varchar(255) CHARACTER SET utf8 NOT NULL,
`announce` varchar(255) CHARACTER SET utf8 NOT NULL,
`content` text CHARACTER SET utf8 NOT NULL,
`hyperlink` varchar(255) CHARACTER SET utf8 NOT NULL,
`ctime` varchar(11) CHARACTER SET utf8 NOT NULL,
`cday` tinyint(2) NOT NULL,
`img` varchar(100) CHARACTER SET utf8 NOT NULL,
`video` text CHARACTER SET utf8 NOT NULL,
`gallery` text CHARACTER SET utf8 NOT NULL,
`comments` int(11) NOT NULL DEFAULT '0',
`views` int(11) NOT NULL DEFAULT '0',
`visibility` enum('1','0') CHARACTER SET utf8 NOT NULL DEFAULT '0',
`pin` tinyint(1) NOT NULL,
`pin_dttm` varchar(10) CHARACTER SET utf8 NOT NULL,
`moderated` tinyint(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Der Index wird als "Ansichten" genannt besteht aus 1-Feld nur - Ansichten. Ich habe auch viele andere Indizes, bestehend aus (zum Beispiel):
feed_id + views + visibility + moderated
moderated + visibility + feed_id + ctime
moderated + visibility + feed_id + views + ctime
Ich benutzte Felder in genannten Reihenfolge, weil das der einzige Grund, warum MySQL war begonnen, sie zu benutzen. In EXPLAIN habe ich jedoch nie "Verwenden wo wo; Verwenden von Index".
Irgendwelche Ideen, wie man EXPLAIN dazu bringt, mir "using index" zu zeigen?
Grundregel: Jedes Feld, das in einem Entscheidungskontext verwendet wird (z. B. verwendet in 'where',' join', 'order by', etc ...) sollte indexiert werden. Ihre Indizes scheinen überflüssig zu sein. Wenn ein Feld in mehreren Indizes angezeigt wird, ist es wahrscheinlich besser, einen eigenen separaten Index zu verwenden. z.B. Wenn die Moderation geändert wird, erzwingen Sie die Änderung von drei separaten Indizes anstelle von nur einem. –
Ich werde die meisten dieser Indizes löschen, wenn ich die beste finde. Es ist nur ein Beispiel dafür, was ich tue, um einen guten Index zu finden. Wie auch immer, danke für deinen Kommentar, ich werde es mir merken. – Greg