Вопрос

У меня есть такой стол

CREATE TABLE IF NOT EXISTS `tbl_folder` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `owner_userid` int(11) NOT NULL,
  `name` varchar(63) NOT NULL,
  `description` text NOT NULL,
  `visibility` tinyint(4) NOT NULL DEFAULT '2',
  `num_items` int(11) NOT NULL DEFAULT '0',
  `num_subscribers` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `owner_userid` (`owner_userid`),
  KEY `vis_sub_item` (`visibility`,`num_subscribers`,`num_items`)
) ENGINE=InnoDB

Поскольку у меня есть индекс на видимости, num_subscribers и num_items, я ожидаю, что вместо этого необходимо рассмотреть только первые 15 строк, объясняющих 55856 строк. Есть идеи? Спасибо

EXPLAIN SELECT t.id, name, description, owner_userid, num_items, num_subscribers
FROM  `tbl_folder`  `t` 
WHERE visibility =2
ORDER BY  `t`.`num_subscribers` DESC ,  `t`.`num_items` DESC 
LIMIT 15

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t ref vis_sub_item vis_sub_item 1 const 55856 Using where
Это было полезно?

Решение

Ваш 3 полевого индекса выглядит хорошо, а EXPLAIN это многообещающе.

Хотя в нем написано «55856 рядов», это всего лишь оценивать предоставлено EXPLAIN.

С key_len =1, Вы знаете, что он использует первый байт вашего составного индекса в качестве равенства/ссылки.

Поскольку в вашем Extra поле, вы знаете, что ORDER BY/сортировка является обрабатывается индексом.

Если вы проверете свой handler_% Сессионная статистика, у вас будет лучшее представление о том, сколько строк на самом деле читается.

Побочные мысли:

Поскольку вы знаете, что в конечном итоге вы нажидете на диск, чтобы забрать строки, если 99% ваших данных имеют visibility=2 (просто спекулируют), вы, вероятно, получите столь же хорошие/быстрые результаты с составным индексом только на num_subscribers & num_items. Анкет Или, возможно, так же хорошо/быстро, если у вас есть один индекс num_subscribers, в зависимости от его кардинальности/уникальности.

Другие советы

Я не думаю, что EXPLAIN смотрит на OFFSET или же LIMIT пункт. EXPLAIN Предполагается указать, как будет выполнен запрос, какие ключи он использовал, как соединяются таблицы и т. Д. LIMIT Пункт похож на модификатор Post Query ... теперь, когда мы знаем, что хотим, дайте им только первое. Таким образом, поле строк содержит количество возможных строк, которые существуют в запросе. Оттуда, OFFSET а также LIMIT Выберите конкретные, которые вы хотите.

Я полагаю, что если вы выполнили свой SELECT без EXPLAIN, вы получите количество записей, которые вы хотели.

Да, проблема в том, что ваш индекс неверен. Я имею в виду, что вы проиндексировали все 3 поля, а ваш выбранное запрос проверяет только один. В MySQL индексация 2 ряда отдельно отличается от индексации 3 строк вместе.

Пытаться

CREATE TABLE IF NOT EXISTS `tbl_folder` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `owner_userid` int(11) NOT NULL,
  `name` varchar(63) NOT NULL,
  `description` text NOT NULL,
  `visibility` tinyint(4) NOT NULL DEFAULT '2',
  `num_items` int(11) NOT NULL DEFAULT '0',
  `num_subscribers` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `owner_userid` (`owner_userid`),
  KEY `vis_index` (`visibility`),
  KEY `vis_sub_item` (`num_subscribers`,`num_items`)
) ENGINE=InnoDB
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top