Я работаю с mysql, запрашивающим таблицу с 12 миллионами регистров, которые являются годом данных. Запрос должен выбрать определенный тип данных (монета, предприятие, тип и т. Д.), А затем предоставить среднесуточное значение для определенных полей этих данных, чтобы потом мы могли графически их отображать. Мечта, чтобы это можно было сделать в режиме реального времени, поэтому время отклика менее 10 секунд, однако на данный момент его не выглядит ярким, поскольку он занимает от 4 до 6 минут. Например, один из запросов содержит 150 тыс. Регистров, разбивается примерно на 500 в день, а затем мы усредняем три поля (которые не входят в предложение where) с использованием AVG() и GroupBy.Оптимизация запросов MySQL в большой таблице
Теперь, к сырым данным, запрос
SELECT
`Valorizacion`.`fecha`, AVG(tir) AS `tir`, AVG(tirBase) AS `tirBase`, AVG(precioPorcentajeValorPar) AS `precioPorcentajeValorPar`
FROM `Valorizacion` USE INDEX (ix_mercado2)
WHERE
(Valorizacion.fecha >= '2011-07-17') AND
(Valorizacion.fecha <= '2012-07-18') AND
(Valorizacion.plazoResidual >= 365) AND
(Valorizacion.plazoResidual <= 3650000) AND
(Valorizacion.idMoneda_cache IN ('UF')) AND
(Valorizacion.idEmisorFusionado_cache IN ('ABN AMRO','WATTS', ...)) AND
(Valorizacion.idTipoRA_cache IN ('BB', 'BE', 'BS', 'BU'))
GROUP BY `Valorizacion`.`fecha` ORDER BY `Valorizacion`.`fecha` asc;
248 rows in set (4 min 28.82 sec)
Индекс производится по всем где полям Оговорки в порядке
(fecha, idTipoRA_cache, idMoneda_cache, idEmisorFusionado_cache, plazoResidual)
Выбор «где» регистры, без использования группа или AVG
149670 rows in set (58.77 sec)
И выбирая регистры, группируя и просто делая счет (*) istead в среднем занимает
248 rows in set (35.15 sec)
Который, вероятно, его потому, что оно не нужно идти на диск для поиска данных, но его получают непосредственно из индекса запросов.
Так как это касается идеи сказать моему боссу «Мне жаль, но это не может быть сделано», но прежде чем это сделать, я прихожу к вам, ребята, спрашивая, думаете ли вы, что я могу что-то сделать, чтобы улучшить это , Я думаю, что я мог бы улучшить поиск по индексу, перемещая индекс с наибольшей мощностью на фронт и т. Д., Но даже после этого время, которое требуется для доступа к диску для каждой записи, и AVG кажется слишком большим.
Любые идеи?
- EDIT, структура таблицы
CREATE TABLE `Valorizacion` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idInstrumento` int(11) NOT NULL,
`fecha` date NOT NULL,
`tir` decimal(10,4) DEFAULT NULL,
`tirBase` decimal(10,4) DEFAULT NULL,
`plazoResidual` double NOT NULL,
`duracionMacaulay` double DEFAULT NULL,
`duracionModACT365` double DEFAULT NULL,
`precioPorcentajeValorPar` decimal(20,15) DEFAULT NULL,
`valorPar` decimal(20,15) DEFAULT NULL,
`convexidad` decimal(20,15) DEFAULT NULL,
`volatilidad` decimal(20,15) DEFAULT NULL,
`montoCLP` double DEFAULT NULL,
`tirACT365` decimal(10,4) DEFAULT NULL,
`tipoVal` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`idEmisorFusionado_cache` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`idMoneda_cache` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`idClasificacionRA_cache` int(11) DEFAULT NULL,
`idTipoRA_cache` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`fechaPrepagable_cache` date DEFAULT NULL,
`tasaEmision_cache` decimal(10,4) DEFAULT NULL,
PRIMARY KEY (`id`,`fecha`),
KEY `ix_FechaNemo` (`fecha`,`idInstrumento`) USING BTREE,
KEY `ix_mercado_stackover` (`idMoneda_cache`,`idTipoRA_cache`,`idEmisorFusionado_cache`,`plazoResidual`)
) ENGINE=InnoDB AUTO_INCREMENT=12933194 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Если добавление индекса является опцией (он будет блокировать таблицу на некоторое время), попробуйте добавить это: idMoneda_cache, idTipoRA_cache, idEmisorFusionado_cache, plazoResidual' (не уверен, что 'plazoResidual' или' fecha' должно быть последним). И затем запустите его (или «EXPLAIN') без« USE INDEX ». Причина в том, что MySQL будет использовать индекс только в поле, для которого существует условие диапазона (в вашем случае вы используете только столбец 'fecha' из вашего индекса). – Vatev
Это имеет большой смысл, теперь до 1 минуты 2 секунды. Строки: 193763. Дополнительно: использование где; Использование временных; Использование filesort. Однако все еще слишком медленно, чтобы поместить его на веб-страницу = | – Jimmy
все еще не очень полезен ... можете ли вы опубликовать 'SHOW CREATE TABLE ...' (возможно, без каких-либо несоответствующих столбцов) и полный вывод 'EXPLAIN' – Vatev