Previous Entry Share Next Entry
что не так с индексом по TIMESTAMP?
1
white_thesis wrote in ru_mysql

Мускуль/win32 5.5.25

Таблица myisam, в которой есть timestamp, по которому сделан индекс

EXPLAIN SELECT * FROM `a2` WHERE `timestamp` < '2011-01-01'
индекс не используется.

однако
EXPLAIN SELECT * FROM `a2` WHERE `timestamp` < unix_timestamp('2011-01-01')
или
EXPLAIN SELECT * FROM `a2` WHERE `timestamp` < 100000
а тут используется

Подскажите pls что поправить мускулю в настройках, чтобы он использовал индекс для первого примера запроса?




UPD

В таблице а2 100 записей. Это кусок боевой таблицы на 7кк записей.

Всего уникальных timestamp в a2 4 штуки
2010-12-18 19:39:45
2010-12-18 21:33:21
2010-12-18 21:33:22
2011-01-30 19:55:09

CREATE TABLE `a2`
(
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`chid` smallint(5) unsigned NOT NULL COMMENT 'source channel number',
`good` tinyint(1) NOT NULL DEFAULT '1',
`pfx` varchar(16) NOT NULL,
`list_id` smallint(5) unsigned NOT NULL DEFAULT '0',
`orig_id` smallint(5) unsigned NOT NULL DEFAULT '0',
`dt` char(6) NOT NULL,
`sfx` varchar(16) NOT NULL,
`hdrlen` tinyint(3) unsigned NOT NULL,
`body` varchar(20000) NOT NULL,
`dupe` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '0-no,1-channel,2-flow',
PRIMARY KEY (`id`),
KEY `list_id` (`list_id`),
KEY `timestamp` (`timestamp`)
)
ENGINE=MyISAM AUTO_INCREMENT=636 DEFAULT CHARSET=cp1251 COMMENT='messages archive table'

Поиск в таблице по
SELECT * FROM `a2` WHERE `timestamp` < '2010-12-18 21:33:22'
Работает нормально, находит сколько и есть.

Тем не менее
EXPLAIN SELECT * FROM `a2` WHERE `timestamp` < '2010-12-18 21:33:22'

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a2 ALL NULL NULL NULL NULL 100 Using where

В то же время
SELECT * FROM `a2` WHERE `timestamp` < UNIX_TIMESTAMP('2010-12-18 21:33:22')
НЕ работает. ничего не находит.
SELECT * FROM `a2` WHERE `timestamp` > UNIX_TIMESTAMP('2010-12-18 21:33:22')
Находит все 100 записей Ж)
То есть условие ставится некорректно.

Однако при этом
EXPLAIN SELECT * FROM `a2` WHERE `timestamp` > unix_timestamp( '2010-12-18 21:33:22' )

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a2 ALL timestamp NULL NULL NULL 100 Using where

И еще более занятно
EXPLAIN SELECT * FROM `a2` WHERE `timestamp` < 567

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a2 range timestamp timestamp 4 NULL 1 Using where

Для условия timestamp < '2010-12-18 21:33:22' мускуль полагает отсуствие ключей вообще
Для условия timestamp < unix_timestamp('2010-12-18 21:33:22') -- possible_keys таки есть и это timestamp, но ключ все равно не задействован

Для условия timestamp < 567 -- possible_keys=timestamp и ключ использован. Хотя все равно ни черта не найдено, но это уже детали


Проверил на другом серваке. Фрюникс, mysql version: 5.1.60

EXPLAIN SELECT *
FROM `a2`
WHERE moment >= '2011-01-01 0:00'
AND moment < '2011-01-05 0:00'

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a2 range timestamp timestamp 4 NULL 1 Using where

Вполне очевидно, что проблема с ключами - локальная. Либо это косяк настройки мускуля либо бага конкретно этой версии Мускуль/win32 5.5.25

  • 1
1. Какого типа поле-то?

Если timestamp, то 2 и 3 запросы имеют мало смысла

2. Сколько записей в таблице?

3. Какое число записей выбирается предикатом `timestamp` < '2011-01-01'?

Edited at 2014-09-08 11:12 pm (UTC)

да, unix timestamp это просто длинное число, и не очень ясно как можно выполнить первый запрос. они несовместимы. Вероятно индекс используется, когда предикат совпадает по типу с колонкой. А первая строчка - просто сравнение контента со строкой

> А первая строчка - просто сравнение контента со строкой

Не совсем так. Литерал '2011-01-01' - один из способов записи дат в mysql (см. http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html)

Так что если столбец timestamp типа date, datetime или timestamp то они вполне себе будут сравниваться как даты.

Edited at 2014-09-09 06:14 am (UTC)

покажите результат show create table `a2`

И полный вывод EXPLAIN заодно

100 записей слишком мало чтобы смотреть планы выполнения. СУБД проще выполнить фулскан, ибо они так и так уже в каком-нибудь из кэшей болтаются.

Налейте туда хотя бы 10к

Всё тоже самое я проверял на боевой таблице. Там > 7 миллионов записей. Только поэтому и заметил, что простейший запрос две минуты выполняется.

EXPLAIN SELECT *
FROM `archive`
WHERE `timestamp` <= '2010-12-18 19:39:45'


id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE archive ALL NULL NULL NULL NULL 7493537 Using where

Edited at 2014-09-10 11:53 am (UTC)

Сколько записей удовлетворяют указанному запросу?

97 штук

SELECT count( * )
FROM `archive`
WHERE timestamp >= '2011-01-01 0:00'
AND timestamp < '2011-03-01 0:00'

Вывод - 1816808

Edited at 2014-09-10 12:37 pm (UTC)

А что если попробовать запустить ANALYZE и OPTIMIZE для таблицы?

  • 1
?

Log in

No account? Create an account