MySQL: почему Order By ID работает намного медленнее, чем Order By других столбцов? - PullRequest
13 голосов
/ 28 сентября 2011

Я использую MySQL версии 5.5.14 для выполнения следующего запроса QUERY 1 из таблицы из 5 миллионов строк:

SELECT P.ID, P.Type, P.Name, P.cty
     , X(P.latlng) as 'lat', Y(P.latlng) as 'lng'
     , P.cur, P.ak, P.tn, P.St, P.Tm, P.flA, P.ldA, P.flN
     , P.lv, P.bd, P.bt, P.nb
     , P.ak * E.usD as 'usP' 
FROM PIG P 
  INNER JOIN EEL E 
    ON E.cur = P.cur 
WHERE act='1' 
  AND flA >= '1615' 
  AND ldA >= '0' 
  AND yr >= (YEAR(NOW()) - 100) 
  AND lv >= '0' 
  AND bd >= '3' 
  AND bt >= '2' 
  AND nb <= '5' 
  AND cDate >= NOW() 
  AND MBRContains(LineString( Point(39.9097, -2.1973)
                            , Point(65.5130, 41.7480)
                            ), latlng) 
  AND Type = 'g' 
  AND tn = 'l' 
  AND St + Tm - YEAR(NOW()) >= '30' 
HAVING usP BETWEEN 300/2 AND 300 
ORDER BY ak
LIMIT 100;

Используя индекс (Type, tn, act, flA) , я могу получить результаты в течение 800 мс . В QUERY 2 я изменил предложение ORDER BY на lv, я также могу получать результаты в течение аналогичных периодов времени. В QUERY 3 я изменил предложение ORDER BY на ID, и время запроса резко сократилось до полных 20 с в среднем на 10 попыток.

Выполнение оператора EXPLAIN SELECT создает точно такой же план выполнения запроса:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: P
         type: range
possible_keys: Index
          key: Index
      key_len: 6
          ref: NULL
         rows: 132478
        Extra: Using where; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: E
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 3
          ref: BS.P.cur
         rows: 1
        Extra: 

Мой вопрос: почему упорядочение по идентификатору в QUERY 3 выполняется так медленно по сравнению с остальными?

Частичное определение таблицы таково:

CREATE TABLE `PIG` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `lv` smallint(3) unsigned NOT NULL DEFAULT '0',
  `ak` int(10) unsigned NOT NULL DEFAULT '0',

  PRIMARY KEY (`ID`),
  KEY `id_ca` (`cty`,`ak`),
  KEY `Index` (`Type`, `tn`, `act`, `flA`),
) ENGINE=MyISAM AUTO_INCREMENT=5000001 DEFAULT CHARSET=latin1

CREATE TABLE `EEL` (
  `cur` char(3) NOT NULL,
  `usD` decimal(11,10) NOT NULL,
  PRIMARY KEY (`cur`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

ОБНОВЛЕНИЕ: После тщательного тестирования различных опций ORDER BY я подтвердил, что столбец идентификатора, который является Первичным ключом, является единственным, вызывающим медленное время запроса.

Ответы [ 3 ]

3 голосов
/ 30 сентября 2011

Из документации MySQL на http://dev.mysql.com/doc/refman/5.6/en/order-by-optimization.html

В некоторых случаях MySQL не может использовать индексы для разрешения ORDER BY, хотя он все еще использует индексы для поиска строк, которые соответствуют предложению WHERE. Эти случаи включают в себя следующее:

. , .

Ключ, используемый для извлечения строк, отличается от ключа, используемого в ORDER BY:

`SELECT * FROM t1 WHERE key2=constant ORDER BY key1;`

Это, вероятно, не поможет, но что произойдет, если вы добавите AND ID > 0 к предложению WHERE? Это заставило бы MySQL использовать первичный ключ для сортировки? Полагаю, стоит попробовать.

(Кажется странным, что упорядочение с помощью ak эффективно, поскольку у ak даже нет индекса, но это может быть связано с меньшим количеством значений для ak?)

1 голос
/ 14 июля 2014

вы можете использовать force index(PRIMARY), попробуйте, и вы увидите в запросе объяснения, что mysql теперь будет использовать индекс первичного ключа, когда 'order by'

0 голосов
/ 28 сентября 2011

Если условие в предложении WHERE отличается от условия в ORDER BY или оно не является частью составного индекса, тогда сортировка происходит не в механизме хранения, а скорее на уровне сервера MySQL, который намного медленнее , Короче говоря, вы должны перестроить свои индексы, чтобы удовлетворить как фильтрацию строк, так и сортировку.

...