системы является Amazon RDS (MySql 5.6.x), Moodle 2.8 на основе программного обеспечения Вот таблица, что я в настоящее время работает над:Оптимизация SQL-запрос в MySQL 5.6
CREATE TABLE `mdl_course_categories` (
`id` bigint(10) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '',
`idnumber` varchar(100) DEFAULT NULL,
`description` longtext,
`descriptionformat` tinyint(2) NOT NULL DEFAULT '0',
`parent` bigint(10) NOT NULL DEFAULT '0',
`sortorder` bigint(10) NOT NULL DEFAULT '0',
`coursecount` bigint(10) NOT NULL DEFAULT '0',
`visible` tinyint(1) NOT NULL DEFAULT '1',
`visibleold` tinyint(1) NOT NULL DEFAULT '1',
`timemodified` bigint(10) NOT NULL DEFAULT '0',
`depth` bigint(10) NOT NULL DEFAULT '0',
`path` varchar(255) NOT NULL DEFAULT '',
`theme` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `mdl_courcate_par_ix` (`parent`),
KEY `mdl_carcoute_tmid` (`timemodified`,`id`),
KEY `mdl_tm_field` (`timemodified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
оригинальный запрос я имел внешность как это:
SELECT
id,
name,
description,
FROM_UNIXTIME(timemodified) AS timemodified,
timemodified AS traw
FROM
mdl_course_categories
WHERE
timemodified BETWEEN 1360602072 AND 1446736233
OR
id > 0
ORDER BY id ASC
LIMIT 0 , 50000
Объяснить этот запрос:
+----+-------------+-----------------------+-------+----------------------------------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------------------+-------+----------------------------------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | mdl_course_categories | index | PRIMARY,mdl_carcoute_tmid,mdl_tm_field | PRIMARY | 8 | NULL | 68 | 100.00 | Using where |
+----+-------------+-----------------------+-------+----------------------------------------+---------+---------+------+------+----------+-------------+
Я предложил база данных специалиста, чтобы избежать или и преобразовать запрос в это:
SELECT * FROM
(
(
SELECT
id,
name,
description,
FROM_UNIXTIME(timemodified) AS timemodified,
timemodified AS traw
FROM
mdl_course_categories
WHERE
timemodified BETWEEN 1360602072 AND 1446736233
)
UNION ALL
(
SELECT
id,
name,
description,
FROM_UNIXTIME(timemodified) AS timemodified,
timemodified AS traw
FROM
mdl_course_categories
WHERE
id > 0
)
) t
ORDER BY id ASC
LIMIT 0 , 50000
Объяснить выглядит так:
+----+--------------+-----------------------+-------+--------------------------------+-------------------+---------+------+------+----------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+-----------------------+-------+--------------------------------+-------------------+---------+------+------+----------+-----------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 80 | 100.00 | Using filesort |
| 2 | DERIVED | mdl_course_categories | range | mdl_carcoute_tmid,mdl_tm_field | mdl_carcoute_tmid | 8 | NULL | 12 | 100.00 | Using index condition |
| 3 | UNION | mdl_course_categories | range | PRIMARY | PRIMARY | 8 | NULL | 68 | 100.00 | Using where |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+-----------------------+-------+--------------------------------+-------------------+---------+------+------+----------+-----------------------+
Что вы думаете? Можно ли это сделать лучше?
Я вижу, что вы используете UNION вместо UNION ALL. Я думал, что UNION медленнее из-за неявного DISTINCT? –
Кроме того, объяснение возвращает по существу тот же план, что и в моей версии запроса union, так где же оптимизация? Просто для уменьшения количества обработанных записей? –
@DarkoMiletic. , , Это должно быть «UNION ALL». И, да, эффективность в количестве обрабатываемых строк. –