Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Приветствую, Коллеги.
Поделитесь плиз соображениями по сабжу.
Есть две похожих таблицы, которые отличаются только тем, что у первой индекс только на одно поле, а у второй - накрывающий, на оба поля в таблице.
CREATE TABLE `exp1_1440_t` (
`t` int(11) NOT NULL AUTO_INCREMENT,
`d` bigint(20) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
KEY `t` (`t`)
) ENGINE=MyISAM AUTO_INCREMENT=1441 DEFAULT CHARSET=utf8;
CREATE TABLE `exp1_1440_td` (
`t` int(11) NOT NULL AUTO_INCREMENT,
`d` bigint(20) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
KEY `td` (`t`,`d`)
) ENGINE=MyISAM AUTO_INCREMENT=1441 DEFAULT CHARSET=utf8;
В каждой таблице по 1440 записей, дамп приложен.
Цель - запросом, который вписывается в реляционную модель БД выбрать максимальный перепад.
Рассматриваются два варианта, возвращающих один и тот же результат, и построенные схожим образом.
На таблице exp1_1440_t c одиночным индексом на поле t:
SELECT MAX((SELECT d FROM exp1_1440_t t2 WHERE t2.t>t1.t ORDER BY t2.t LIMIT 1) - t1.d) FROM exp1_1440_t t1;
и
SELECT MAX(t1.d-(SELECT d FROM exp1_1440_t t2 WHERE t2.t<t1.t ORDER BY t2.t DESC LIMIT 1)) FROM exp1_1440_t t1;
Выполняются они примерно одно и то же время - 1.16 сек.
explain'ы совпадают.
mysql> explain SELECT MAX((SELECT d FROM exp1_1440_t t2 WHERE t2.t>t1.t ORDER BY t2.t LIMIT 1) - t1.d) FROM exp1_1440_t t1; +----+--------------------+-------+-------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+-------+-------+---------------+------+---------+------+------+-------------+ | 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 1440 | | | 2 | DEPENDENT SUBQUERY | t2 | index | t | t | 4 | NULL | 1 | Using where | +----+--------------------+-------+-------+---------------+------+---------+------+------+-------------+ 2 rows in set (0.00 sec) mysql> explain SELECT MAX(t1.d-(SELECT d FROM exp1_1440_t t2 WHERE t2.t<t1.t ORDER BY t2.t DESC LIMIT 1)) FROM exp1_1440_t t1; +----+--------------------+-------+-------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+-------+-------+---------------+------+---------+------+------+-------------+ | 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 1440 | | | 2 | DEPENDENT SUBQUERY | t2 | index | t | t | 4 | NULL | 1 | Using where | +----+--------------------+-------+-------+---------------+------+---------+------+------+-------------+ 2 rows in set (0.00 sec)
Все вроде логично.
Но если использовать накрывающий индекс td(t,d), то становится непонятней.
explain'ы опять же совпадают:
mysql> explain SELECT MAX((SELECT d FROM exp1_1440_td t2 WHERE t2.t>t1.t ORDER BY t2.t LIMIT 1) - t1.d) FROM exp1_1440_td t1; +----+--------------------+-------+-------+---------------+------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+-------+-------+---------------+------+---------+------+------+--------------------------+ | 1 | PRIMARY | t1 | index | NULL | td | 13 | NULL | 1440 | Using index | | 2 | DEPENDENT SUBQUERY | t2 | index | td | td | 13 | NULL | 1 | Using where; Using index | +----+--------------------+-------+-------+---------------+------+---------+------+------+--------------------------+ 2 rows in set (0.00 sec) mysql> explain SELECT MAX(t1.d-(SELECT d FROM exp1_1440_td t2 WHERE t2.t<t1.t ORDER BY t2.t DESC LIMIT 1)) FROM exp1_1440_td t1; +----+--------------------+-------+-------+---------------+------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+-------+-------+---------------+------+---------+------+------+--------------------------+ | 1 | PRIMARY | t1 | index | NULL | td | 13 | NULL | 1440 | Using index | | 2 | DEPENDENT SUBQUERY | t2 | index | td | td | 13 | NULL | 1 | Using where; Using index | +----+--------------------+-------+-------+---------------+------+---------+------+------+--------------------------+ 2 rows in set (0.00 sec)
А вот время выполнения сильно отличается
mysql> SELECT MAX((SELECT d FROM exp1_1440_td t2 WHERE t2.t>t1.t ORDER BY t2.t LIMIT 1) - t1.d) FROM exp1_1440_td t1; +-----------------------------------------------------------------------------------+ | MAX((SELECT d FROM exp1_1440_td t2 WHERE t2.t>t1.t ORDER BY t2.t LIMIT 1) - t1.d) | +-----------------------------------------------------------------------------------+ | 99 | +-----------------------------------------------------------------------------------+ 1 row in set (0.41 sec) mysql> SELECT MAX(t1.d-(SELECT d FROM exp1_1440_td t2 WHERE t2.t<t1.t ORDER BY t2.t DESC LIMIT 1)) FROM exp1_1440_td t1; +--------------------------------------------------------------------------------------+ | MAX(t1.d-(SELECT d FROM exp1_1440_td t2 WHERE t2.t<t1.t ORDER BY t2.t DESC LIMIT 1)) | +--------------------------------------------------------------------------------------+ | 99 | +--------------------------------------------------------------------------------------+ 1 row in set (2.78 sec)
Собственно, в этом и вопрос - в чем разница в выполнении этих запросов?, почему такая существенная разница в скорости?
Неактивен
Прикольно
Различие на этапе Sending data в подзапросах. Ощущение, что это overhead
из-за того, что приходится разворачивать индекс в памяти (бегать задом напе-
ред). Возможно, какой-то плохо оптимизированный кусок кода в этом месте.
Неактивен
Класс! А мораль отсюда можно какую-то вывести?
Неактивен
Мораль проста: не нужно использовать базу данных в качестве языка программирования
Неактивен
Ну то есть либо вытащить все данные из таблицы на клиент и там на процедурном языке спокойно посчитать всё что нужно, либо курсором пробежать по таблице в хранимой процедурке и сделать примерно то же самое?
Неактивен
Я подозреваю, что даже в базе пробежать с переменной один раз по таблице
будет быстрее
Неактивен
Понятно. Спасибо .
Неактивен
По моему ещё один классический пример когда эффективно использовать переменные.
Неактивен
Страниц: 1