SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 10.11.2011 10:56:56

Edd_Layer
Участник
Зарегистрирован: 10.11.2011
Сообщений: 2

Оптимизация и индексы

Перечитал все темы по оптимизации на форуме, но остались неясные моментыsmile
переделываю клиентское приложение с базой сделанное до меня и честно говоря не очень знаком с mysql, а спросить более не у кого.

решил сделать нагрузочный тест.
заполнил таблицу записями в количестве одного миллиона (1 000 000)

изначально обеспокоился тем, что запрос


SELECT defects.Printed, defects.Date, defects.Time, device.Name, defects.VagNo, defects.DetNo, dettypes.Name, defects.DetParameter, defects.ProdYear, factory.Short, humans.FullName, defects.DefectNo, zones.Name, defectref.Name, defects.DefectSize, defects.Amplitude, results.Short, defects.Errors
FROM defects
LEFT OUTER JOIN device ON (defects.Device = device.ID)
LEFT OUTER JOIN dettypes ON (defects.DetTypeId = dettypes.ID)
LEFT OUTER JOIN factory ON (defects.ZavNo = factory.Cod)
LEFT OUTER JOIN humans ON (defects.DefectoscopistID = humans.TabNo)
LEFT OUTER JOIN zones ON (defects.DetTypeId * 100 + defects.ZoneID) = zones.DetTypeZone
LEFT OUTER JOIN defectref ON (defects.DefectID = defectref.ID)
LEFT OUTER JOIN results ON (defects.Result = results.ID)
ORDER BY humans.FullName, defects.Date, defects.Time;
 


долго выполняется (не хватало терпения дождаться). 
поковырялся, ускорил тем, что сделал кой-какие дополнительные индексы в таблицах humans и factory

(поскольку база была сделана до меня, названия и архитектура может быть корявой, а менять пока боюсь из соображений преемтсвенности)

сейчас выполняется он за 97 сек.

EXPLAIN:


+----+-------------+-----------+--------+---------------+---------+---------+------------------------------+---------+----------
| id | select_type | table     | type   | possible_keys | key     | key_len | ref                          | rows    | Extra   |
+----+-------------+-----------+--------+---------------+---------+---------+------------------------------+---------+---------
|  1 | SIMPLE      | defects   | ALL    | NULL          | NULL    | NULL    | NULL | 1000000 | Using temporary; Using filesort |
|  1 | SIMPLE      | device    | eq_ref | PRIMARY       | PRIMARY | 4       | rmd.defects.Device           |       1 |
|  1 | SIMPLE      | dettypes  | eq_ref | PRIMARY       | PRIMARY | 4       | rmd.defects.DetTypeId        |       1 |         |
|  1 | SIMPLE      | factory   | ref    | i_Cod         | i_Cod   | 5       | rmd.defects.ZavNo            |       2 |
|  1 | SIMPLE      | humans    | ref    | i_tabno       | i_tabno | 5       | rmd.defects.DefectoscopistID |      11 |
|  1 | SIMPLE      | zones     | eq_ref | PRIMARY       | PRIMARY | 4       | func                         |       1 |
|  1 | SIMPLE      | defectref | eq_ref | PRIMARY       | PRIMARY | 4       | rmd.defects.DefectID         |       1 |
|  1 | SIMPLE      | results   | eq_ref | PRIMARY       | PRIMARY | 4       | rmd.defects.Result           |       1 |
 


1. вопрос:
видно что в defects не использованы какие либо ключи, может быть поэтому запрос занимает полторы минуты?


упростил:
запрос SELECT * FROM defects; даёт 4,6 сек


2. вопрос:
понимаю что всё относительно и зависит от производительности машины,
но всё же люди с большим опытом наверно могут сказать удобоварим ли показатель для такого количества записей
с этим запросом за 5 сек?


EXPLAIN SELECT * FROM defects;

+----+-------------+---------+------+---------------+------+---------+------+---------+-------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows    | Extra |
+----+-------------+---------+------+---------------+------+---------+------+---------+-------+
|  1 | SIMPLE      | defects | ALL  | NULL          | NULL | NULL    | NULL | 1000000 |       |
+----+-------------+---------+------+---------------+------+---------+------+---------+-------+
 


3. вопрос:
не понимаю почему все же не используются индексы в таблице defects или это нормально?

хотя индексов там много:

CREATE TABLE  `rmd`.`defects` (
  `ID` int(11) NOT NULL auto_increment,
  `MyId` int(11) default NULL,
  `Date` date default NULL,
  `DefectoscopistID` int(11) default NULL,
  `VagNo` char(10) default NULL,
  `DetTypeId` int(11) default NULL,
  `DetNo` char(10) default NULL,
  `DetParameter` int(11) default NULL,
  `DefectNo` int(11) default NULL,
  `ZavNo` char(10) default NULL,
  `ProdYear` int(11) default NULL,
  `Time` time default NULL,
  `ZoneID` int(11) default NULL,
  `Result` int(11) default NULL,
  `DefectID` int(11) default NULL,
  `DefectSize` int(11) default NULL,
  `Amplitude` int(11) default NULL,
  `Printed` tinyint(1) default NULL,
  `CRC32` int(11) default NULL,
  `Device` int(11) default NULL,
  `Errors` int(11) default NULL,
  PRIMARY KEY  (`ID`),
  KEY `i_Errors` (`Errors`),
  KEY `i_MyId` (`MyId`),
  KEY `i_Date` (`Date`),
  KEY `i_DefectoscopistID` (`DefectoscopistID`),
  KEY `i_VagNo` (`VagNo`),
  KEY `i_DetTypeId` (`DetTypeId`),
  KEY `i_DetNo` (`DetNo`),
  KEY `i_DetParameter` (`DetParameter`),
  KEY `i_ZavNo` (`ZavNo`),
  KEY `i_ProdYear` (`ProdYear`),
  KEY `i_Time` (`Time`),
  KEY `i_ZoneID` (`ZoneID`),
  KEY `i_Result` (`Result`),
  KEY `i_DefectID` (`DefectID`),
  KEY `i_Device` (`Device`)
) ENGINE=MyISAM AUTO_INCREMENT=1000001 DEFAULT CHARSET=cp1251;
 


и последний общий вопрос: уважаемые эксперты, подскажите что можно и нужно скорректировать?

спасибоsmile

p.s.: может быть джоины переписать как-то более оптимально следует?
но обязательно требуется подставлять информацию из справочник в основную таблицу defects

Отредактированно Edd_Layer (10.11.2011 11:13:41)

Неактивен

 

#2 10.11.2011 22:38:20

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: Оптимизация и индексы

Ну индексы тут не причем так как, во всех случаях вы вынимаете абсолютно все данные из таблицы defects, то есть нет никакого условия.
А какая надобность вынимать миллион записей ?

Неактивен

 

#3 11.11.2011 18:16:48

Edd_Layer
Участник
Зарегистрирован: 10.11.2011
Сообщений: 2

Re: Оптимизация и индексы

да я уж подумал в самом деле никакой надобности, надо просто ввести условия и вынимать за последний месяц или использовать LIMIT.

в предыдущей версии приложения реализовано не было и вытаскивались по умолчанию все имеющиеся записи. но до большого количества еще не доходило. а я решил потестить и вот, натолкнуло на мысли что в приложении надо что-то менятьsmile
спасибо)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson