Я знаю, что этот вопрос задан несколько раз, но я не смог сделать свой запрос достаточно быстрым, прочитав эти ответы.Как правильно увеличить производительность MySQL путем индексирования
В принципе, у меня есть таблица с 400k строк. Раньше у него было более 1,8 м строк, время запроса - более 17 секунд, поэтому у меня есть задание cron, чтобы отключить записи старше 5 дней в этой таблице, чтобы сохранить записи примерно в 400 тыс. Строк, чтобы время запроса было чуть больше 5 сек и 5 секунд все еще медленно. У нас есть еще несколько таблиц, которые содержат более 2 миллионов записей и используют JOIN, поэтому я предпочитаю сначала решить эту таблицу трендов, чтобы получить больше exp, а затем коснуться других, чтобы повысить производительность запросов в более сложных случаях.
Структура данных:
| _id | doctype | subtype | term | user_id | nug_id | source | timestamp | confidence |
|-----|---------|---------|------|---------|---------|--------|-----------|------------|
| 123 | post | keyword | games| 1000 | 200 | twitter| 143389203 | 0.|
Я индексировали term
, timestamp
, source
, confidence
.
Обычно мой запрос:
SELECT term, SUM(confidence) AS relevance FROM trends
WHERE source IN ("twitter", "tumblr", "instagram", "post", "flickr")
GROUP BY term ORDER BY relevance DESC
А вот мой результат:
Showing rows 0 - 29 (165032 total, Query took 5.8050 sec)
Так что я должен делать дальше, чтобы оптимизировать индекс или запрос для повышения производительности. Теперь я могу предвидеть, насколько плохо мое время запроса будет, когда я запрашиваю JOIN.
Add1: Извините, я забыл приложить выход EXPLAIN.
ADD2: Структура таблицы
CREATE TABLE `trends` (
`_id` bigint(20) NOT NULL AUTO_INCREMENT,
`doctype` varchar(10) DEFAULT NULL,
`subtype` varchar(20) DEFAULT NULL,
`term` varchar(200) DEFAULT NULL,
`user_id` varchar(100) DEFAULT NULL,
`nug_id` varchar(100) DEFAULT NULL,
`timestamp` bigint(20) DEFAULT NULL,
`source` varchar(100) DEFAULT NULL,
`confidence` float DEFAULT NULL,
PRIMARY KEY (`_id`),
KEY `confidence` (`confidence`),
KEY `give_me_trends` (`user_id`,`source`),
KEY `term` (`term`,`source`),
KEY `timestamp` (`timestamp`,`confidence`),
KEY `source` (`source`)
) ENGINE=InnoDB AUTO_INCREMENT=95350350 DEFAULT CHARSET=utf8
Add3:
После того, как создана новая таблица называется test_trends
и скопировать данные из trends
таблицы, я протестирована с source
колонны в виде целого числа , Также я удалил два столбца doctype
и subtype
, поскольку они не нужны вообще. Запрашивается ниже:
SELECT term, SUM(confidence) AS relevance FROM test_trends
WHERE source IN (1,2,3,4,5,6,7)
GROUP BY term ORDER BY relevance DESC
в 5.4802 сек.
EXPLAIN, как показано ниже:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|-----|-------------|-------------|--------|-------------------|---------|-----------|--------|--------|----------------------------------------------|
| 1 | SIMPLE | test_trends | index | source,source_2 | term_2 | 603 | NULL | 354324 | Using where; Using temporary; Using filesort |
add4:
Моя тестовая структура таблицы:
CREATE TABLE `test_trends` (
`_id` bigint(20) NOT NULL AUTO_INCREMENT,
`term` varchar(200) DEFAULT NULL,
`user_id` varchar(100) DEFAULT NULL,
`nug_id` varchar(100) DEFAULT NULL,
`timestamp` bigint(20) DEFAULT NULL,
`source` tinyint(1) DEFAULT NULL,
`confidence` float DEFAULT NULL,
PRIMARY KEY (`_id`),
KEY `confidence` (`confidence`),
KEY `give_me_trends` (`user_id`,`source`),
KEY `term` (`term`,`source`),
KEY `timestamp` (`timestamp`,`confidence`),
KEY `source` (`source`),
KEY `term_2` (`term`),
KEY `source_2` (`source`,`confidence`,`timestamp`)
) ENGINE=InnoDB AUTO_INCREMENT=95354268 DEFAULT CHARSET=utf8
Также я индексироваться term
, source
, confidence
, timestamp
.
Add5:
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 0 | PRIMARY | 1 | _id | A | 379365 | NULL | NULL | | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | confidence | 1 | confidence | A | 18 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | give_me_trends | 1 | user_id | A | 149 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | give_me_trends | 2 | source | A | 556 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | term | 1 | term | A | 379365 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | term | 2 | source | A | 379365 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | timestamp | 1 | timestamp | A | 13548 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | timestamp | 2 | confidence | A | 189682 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | source | 1 | source | A | 107 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | term_2 | 1 | term | A | 379365 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | source_2 | 1 | source | A | 18 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | source_2 | 2 | confidence | A | 189 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_trends | 1 | source_2 | 3 | timestamp | A | 189682 | NULL | NULL | YES | BTREE | | |
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
Вы пытались использовать "EXPLAIN SELECT ...", чтобы выяснить, как MySQL использует свои индексы? Вы должны хотя бы запустить это и изменить свой вопрос, чтобы содержать вывод. – timdev
Просто отредактированный и добавленный вывод EXPLAIN – noob
@Drew, вы имели в виду использование int, а не varchar для некоторых столбцов, таких как 'source', как это:' 1 = "twitter", 2 = "tumble и т. Д." ' – noob