MySQL простой запрос на выбор медленный - PullRequest
2 голосов
/ 29 марта 2012

У меня есть большой MySQL-стол с примерно 110.000.000 предметов

Дизайн таблицы:

CREATE TABLE IF NOT EXISTS `tracksim` (
`tracksimID` int(11) NOT NULL AUTO_INCREMENT,
`trackID1` int(11) NOT NULL,
`trackID2` int(11) NOT NULL,
`sim` double NOT NULL,
PRIMARY KEY (`tracksimID`),
UNIQUE KEY `TrackID1` (`trackID1`,`trackID2`),
KEY `sim` (`sim`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

Теперь я хочу запросить обычный запрос:

SELECT trackID1, trackID2 FROM `tracksim` 
WHERE sim > 0.5 AND 
      (`trackID1` = 168123 OR `trackID2`= 168123)
ORDER BY sim DESC LIMIT 0,100

Объяснение дает мне:

+----+-------------+----------+-------+---------------+------+---------+------+----------+----------+-------------+
| id | select_type | table    | type  | possible_keys | key  | key_len | ref  | rows     | filtered | Extra       |
+----+-------------+----------+-------+---------------+------+---------+------+----------+----------+-------------+
|  1 | SIMPLE      | tracksim | range | TrackID1,sim  | sim  | 8       | NULL | 19980582 |   100.00 | Using where |
+----+-------------+----------+-------+---------------+------+---------+------+----------+----------+-------------+

Запрос кажется очень медленным (около 185 секунд), но я не знаю, только ли это из-за количества элементов в таблице. У вас есть совет, как я могу ускорить запрос или поиск по таблице?

Ответы [ 3 ]

3 голосов
/ 29 марта 2012

С 110 миллионами записей, я не могу себе представить, что есть много записей с указанным номером трека. Я бы имел такие индексы, как

(trackID1, sim )
(trackID2, sim )
(tracksimID, sim)

и сделайте ЗАКАЗ через объединение и присоединитесь к этому результату

select STRAIGHT_JOIN
      TS2.*
   from
      ( select ts.tracksimID
           from tracksim ts
           where ts.trackID1 = 168123
             and ts.sim > 0.5
        UNION
        select ts.trackSimID
           from tracksim ts
           where ts.trackid2 = 168123
             and ts.sim > 0.5 
      ) PreQuery
      JOIN TrackSim TS2
         on PreQuery.TrackSimID = TS2.TrackSimID
   order by
      TS2.SIM DESC
   LIMIT 0, 100
2 голосов
/ 29 марта 2012

В основном я согласен с Drap, но следующий вариант запроса может быть еще более эффективным, особенно для более крупного LIMIT:

SELECT TS2.*
FROM (
  SELECT tracksimID, sim
  FROM tracksim
  WHERE trackID1 = 168123
    AND sim > 0.5
  UNION
  SELECT trackSimID, sim
  FROM tracksim
  WHERE trackid2 = 168123
    AND ts.sim > 0.5
  ORDER BY sim DESC
  LIMIT 0, 100
) as PreQuery
JOIN TrackSim TS2 USING (TrackSimID);

Требуется (trackID1, sim) и (trackID2, sim) индексы.

0 голосов
/ 29 марта 2012

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

CREATE INDEX TRACK_INDEX
ON tracksim (trackID1)

http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

http://www.tutorialspoint.com/mysql/mysql-indexes.htm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...