Медленно работающий sql на mysql - PullRequest
1 голос
/ 19 июля 2011

Рассмотрим следующую таблицу и ее индексы:

CREATE TABLE 'Interaction' (
  'oid' bigint(20) NOT NULL,
  'archieved' datetime DEFAULT NULL,
  'content' longtext COLLATE utf8_bin,
  'contentSentiment' int(11) DEFAULT NULL,
  'createdAt' datetime DEFAULT NULL,
  'id' varchar(255) COLLATE utf8_bin DEFAULT NULL,
  'interactionSource' longtext COLLATE utf8_bin,
  'link' varchar(255) COLLATE utf8_bin DEFAULT NULL,
  'source' varchar(255) COLLATE utf8_bin DEFAULT NULL,
  'title' varchar(255) COLLATE utf8_bin DEFAULT NULL,
  'type' int(11) DEFAULT NULL,
  'authorKloutScore' int(11) DEFAULT NULL,
  PRIMARY KEY ('oid'),
  KEY 'createdAt' ('createdAt'),
  KEY 'fullMonitorFeedSearch' ('criteria_oid','createdAt','authorKloutScore','archieved','type')
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin

Почему следующий запрос выполняется медленно, если существует индекс (fullMonitorFeedSearch), который его покрывает? Кстати, если 'interactio0_.TYPE = 2' удален, sql запускается через 0,01 с.

SELECT interactio0_.oid 
FROM   Interaction interactio0_ 
WHERE  interactio0_.criteria_oid = 21751021
    AND interactio0_.createdat = 10
    AND interactio0_.archieved IS NULL
    AND interactio0_.TYPE = 2
ORDER  BY interactio0_.createdat DESC 

Это объяснение для sql:

+----+-------------+--------------+-------+--------------------------------------------------------------------------+-----------------------+---------+------+---------+-------------+
| id | select_type | table        | type  | possible_keys                                                            | key                   | key_len | ref  | rows    | Extra       |
+----+-------------+--------------+-------+--------------------------------------------------------------------------+-----------------------+---------+------+---------+-------------+
|  1 | SIMPLE      | interactio0_ | range | FKD15475F24AA96F7,createdAt,fullMonitorFeedSearch                        | fullMonitorFeedSearch | 18      | NULL | 2323027 | Using where |
+----+-------------+--------------+-------+--------------------------------------------------------------------------+-----------------------+---------+------+---------+-------------+

Ответы [ 2 ]

1 голос
/ 19 июля 2011

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

fullMonitorFeedSearch (criteria_oid, type, createdAt, archieved)

Затем измените запрос следующим образом:

SELECT interactio0_.oid
FROM   Interaction interactio0_
WHERE  interactio0_.criteria_oid = 21751021
    AND interactio0_.type = 2
    AND interactio0_.createdat = 10
    AND interactio0_.archieved IS NULL
ORDER BY interactio0_.createdat DESC;

Несколько дополнительных предложений / проблем:

  1. Если столбец type должен содержать такие значения, как 1, 2, 3 ..., я думаюимеет смысл повторно объявить его как TINYINT UNSIGNED.Это должно позволить вам хранить значения в диапазоне от 0 до 255.

  2. Аналогичное предложение для столбцов authorKloutScore и contentSentiment для повторного объявления как TINYINT UNSIGNED или SMALLINT UNSIGNED в зависимости откакие значения может содержать столбец.

  3. Индекс и запрос упоминают столбец criteria_oid, но этот столбец отсутствует в определении таблицы.Я не уверен, что это опечатка или столбец не существует.

  4. Столбец createdAt имеет значение DATETIME, но соответствующий предикат WHERE в запросе не имеет большого значениясмысл - interactio0_.createdat = 10.Не должно ли это быть дата или дата-время в правой части.Или столбец предназначен для хранения только определенных данных (день, месяц или час)?

  5. Одно конкретное условие в запросе читается как interactio0_.criteria_oid = 21751021.Как я уже упоминал выше, столбец отсутствует в определении таблицы.Однако идея заключается в том, что если этот столбец является УНИКАЛЬНЫМ, имеет больше смысла удалить все другие условия WHERE - выберите запись где criteria_oid = 21751021 и выполните другие проверки в наборе результатов в PHP.Однако, если столбец не UNIQUE и может быть много строк с одинаковым creative_oid, тогда запрос вполне подойдет.

Надеюсь, что вышеприведенное поможет!

0 голосов
/ 19 июля 2011

Это может быть проблема с количеством элементов;Что произойдет, если вы создадите конкретный индекс для Типа отдельно?

Кроме того, рассмотрите ваши сценарии данных, что более вероятно - то, что createat будет конкретным, или что архивированное значение равно нулю?

Один изПервичные соображения при оптимизации индексов - это анализ распространенности данных;То есть, если вы индексируете по 4 полям и можете выбрать счетчик, сгруппированный по этим 4 полям, если вы получаете много и много записей, значит, ваш индекс неверен.

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